
// IRISView.cpp : CIRISView 类的实现
//

#include "stdafx.h"
// SHARED_HANDLERS 可以在实现预览、缩略图和搜索筛选器句柄的
// ATL 项目中进行定义，并允许与该项目共享文档代码。
#ifndef SHARED_HANDLERS
#include "IRIS.h"
#endif

#include "IRISDoc.h"
#include "IRISView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CIRISView

IMPLEMENT_DYNCREATE(CIRISView, CFormView)

BEGIN_MESSAGE_MAP(CIRISView, CFormView)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
	ON_EN_CHANGE(IDC_IMAGE_SOURCE, &CIRISView::OnEnChangeImageSource)
	ON_CBN_SELCHANGE(IDC_COMBO_SINGLESTEP, &CIRISView::OnCbnSelchangeComboSinglestep)
	ON_BN_CLICKED(IDC_BUTTON_SELECTSOURCE, &CIRISView::OnBnClickedButtonSelectsource)
	ON_BN_CLICKED(IDC_BUTTON_SELECTTARGET, &CIRISView::OnBnClickedButtonSelecttarget)
	ON_BN_CLICKED(IDC_BUTTON_SAVE, &CIRISView::OnBnClickedButtonSave)
	ON_BN_CLICKED(IDC_BUTTON_EXIT, &CIRISView::OnBnClickedButtonExit)
	ON_BN_CLICKED(IDC_BUTTON_SELECTTARGET2, &CIRISView::OnBnClickedButtonSelecttarget2)
END_MESSAGE_MAP()

// CIRISView 构造/析构

CIRISView::CIRISView()
	: CFormView(CIRISView::IDD)
{
	// TODO: 在此处添加构造代码

}

CIRISView::~CIRISView()
{
}

void CIRISView::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
}

BOOL CIRISView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式

	return CFormView::PreCreateWindow(cs);
}

void CIRISView::OnInitialUpdate()
{

	CFormView::OnInitialUpdate();
	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();
	//设置字体颜色
	static CFont font;
	static CFont font1;
	static CFont font2;
	font.CreatePointFont(300, "宋体");
	GetDlgItem(IDC_STATIC1)->SetFont(&font);
	//GetDlgItem(IDC_STATIC2)->SetFont(&font);
	font1.CreatePointFont(150, "宋体");
	GetDlgItem(IDC_BUTTON_SELECTSOURCE)->SetFont(&font1);
	GetDlgItem(IDC_BUTTON_SELECTTARGET)->SetFont(&font1);
	//GetDlgItem(IDC_BUTTON_SAVE)->SetFont(&font1);
	GetDlgItem(IDC_BUTTON_EXIT)->SetFont(&font1);
	font2.CreatePointFont(320, "宋体");
	GetDlgItem(IDC_STATIC_R1)->SetFont(&font);
	//CComboBox * SingleStepComb=(CComboBox*)GetDlgItem(IDC_COMBO_SINGLESTEP);
	//SingleStepComb->SetCurSel(0);
	CString result;
	result.Format("虹膜识别");
	GetDlgItem(IDC_STATIC_R1)->SetWindowText(result);
}

void CIRISView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
	ClientToScreen(&point);
	OnContextMenu(this, point);
}

void CIRISView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
	theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// CIRISView 诊断

#ifdef _DEBUG
void CIRISView::AssertValid() const
{
	CFormView::AssertValid();
}

void CIRISView::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}

CIRISDoc* CIRISView::GetDocument() const // 非调试版本是内联的
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CIRISDoc)));
	return (CIRISDoc*)m_pDocument;
}
#endif //_DEBUG


// CIRISView 消息处理程序


void CIRISView::OnEnChangeImageSource()
{
	// TODO:  如果该控件是 RICHEDIT 控件，它将不
	// 发送此通知，除非重写 CFormView::OnInitDialog()
	// 函数并调用 CRichEditCtrl().SetEventMask()，
	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。

	// TODO:  在此添加控件通知处理程序代码
}


void CIRISView::OnCbnSelchangeComboSinglestep()
{
	CComboBox * SingleStepComb=(CComboBox*)GetDlgItem(IDC_COMBO_SINGLESTEP);
	int a=SingleStepComb->GetCurSel();
    if(a!=0)
	{  
		CIRISDoc* pDoc=GetDocument();
		if(pDoc->GetHDIB()==NULL)
		{
			MessageBox("请首先选择要处理的虹膜");
			SingleStepComb->SetCurSel(0);
			return;
		}
		int process_state=pDoc->m_state;
		switch(a)
		{  
			case 1 : 
				InnerEdge();
			break;
			case 2 :
				OuterEdge();
			break ;
			case 3:
				NormalRect();
			break;
			case 4:
 				Binarization();
			break;
		} 
	}
}


void CIRISView::OnBnClickedButtonSelectsource()
{
	CIRISDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	CFileDialog dlg(TRUE,"bmp","*.bmp");
	if(dlg.DoModal()==IDOK)//打开位图	
	{
		pDoc->m_FilePath=dlg.GetPathName(); 
		pDoc->OnOpenDocument(pDoc->m_FilePath);
		// 判断是否是8-bpp位图（这里为了方便，只处理8-bpp位图，其它的可以类推）
		LPSTR lpDIB;
		lpDIB=(LPSTR)::GlobalLock((HGLOBAL) pDoc->GetHDIB());
		if (::DIBNumColors(lpDIB)!= 256)
		{
			// 提示用户
			MessageBox("目前只支持查看256色位图灰度直方图！", "系统提示" , MB_ICONINFORMATION | MB_OK);	
			// 解除锁定
			::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
			//消除文档对象的内容
			pDoc->DeleteContents();
			// 返回
			return;
		}
		::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
		CStatic * sta_compare=(CStatic*)GetDlgItem(IDC_STATIC_R1);
		CString str;
		str.Format("");
		sta_compare->SetWindowText(str);
		CDC dc;
		OnDraw(&dc);


		Binarization();
		
		//LPSTR lpDIB = (LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB());
		LPSTR lpDIBBits;
		// 找到DIB图像象素起始位置
		lpDIBBits = ::FindDIBBits(lpDIB);
		::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
		long lWidth = ::DIBWidth(lpDIB);
		long lHeight = ::DIBHeight(lpDIB);
		//建立存储位图灰度的数组
		long threshold = Threshold(lpDIBBits, lWidth, lHeight);
		HGLOBAL	hGlobal = ::GlobalAlloc(GHND, lHeight*lWidth);
		LPSTR lpRecorder = (char*)::GlobalLock(hGlobal);
		::GlobalUnlock(hGlobal);
		memset(lpRecorder, 1, lHeight*lWidth);
		// 图像每行的字节数
		LONG lLineBytes;
		// 计算图像每行的字节数
		lLineBytes = WIDTHBYTES(lWidth * 8);
		PupilContour(lpRecorder, lWidth, lHeight, threshold, lpDIBBits);
		CList<PHTPoint, PHTPoint&>  PointListForPHT;
		FindPHTPoint(hGlobal, &PointListForPHT, lHeight, lWidth);//找到用于PHT变换的各个点；     
		if (PointListForPHT.IsEmpty())
		{
			AfxMessageBox("虹膜无法识别，退出");
			return;
		}
		CIRCLE InnerCircle = PHT(&PointListForPHT);
		PointListForPHT.RemoveAll();
		CIRCLE Outer = OuterCircle(lpDIBBits, lWidth, lHeight, InnerCircle);
		::GlobalFree(hGlobal);
		const long RectWidth = 512;
		const long RectHeight = 128;
		HDIB hDIB = TurnToRect(InnerCircle, Outer, lpDIB, RectWidth, RectHeight);
		LOGBin(hDIB);
		Morphological(hDIB);
		int tab = 0;
		PointInformation pointInfor[255];
		MarkthePoint(hDIB, pointInfor, tab);
		CharacterVector CharaV1[Character_length];
		GetCharacterVector(pointInfor, tab, CharaV1, Character_length);
		//存储特征向量
		FileName_Chara FileCharaV1;
		FileCharaV1.FileName = "虹膜特征数据库.txt";
		FileCharaV1.Chara = CharaV1;
		MySaveCharaV(FileCharaV1, Character_length);
		CStatic * result = (CStatic*)GetDlgItem(IDC_STATIC_R1);
		result->SetWindowText("已成功存储虹膜特征值");
		OnDraw(&dc);
	}
}


void CIRISView::OnBnClickedButtonSelecttarget()
{
	CIRISDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	CFileDialog dlg(TRUE, "bmp", "*.bmp");
	if (dlg.DoModal() == IDOK)//打开位图	
	{
		pDoc->m_FilePath = dlg.GetPathName();
		pDoc->OnOpenDocument(pDoc->m_FilePath);
		// 判断是否是8-bpp位图（这里为了方便，只处理8-bpp位图，其它的可以类推）
		LPSTR lpDIB;
		lpDIB = (LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB());
		if (::DIBNumColors(lpDIB) != 256)
		{
			// 提示用户
			MessageBox("目前只支持查看256色位图灰度直方图！", "系统提示", MB_ICONINFORMATION | MB_OK);
			// 解除锁定
			::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
			//消除文档对象的内容
			pDoc->DeleteContents();
			// 返回
			return;
		}
		::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
		CStatic * sta_compare = (CStatic*)GetDlgItem(IDC_STATIC_R1);
		CString str;
		str.Format("");
		sta_compare->SetWindowText(str);
		CDC dc;
		OnDraw(&dc);
		Binarization();
		//LPSTR lpDIB = (LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIB());
		LPSTR lpDIBBits;
		// 找到DIB图像象素起始位置
		lpDIBBits = ::FindDIBBits(lpDIB);
		::GlobalUnlock((HGLOBAL)pDoc->GetHDIB());
		long lWidth = ::DIBWidth(lpDIB);
		long lHeight = ::DIBHeight(lpDIB);
		//建立存储位图灰度的数组
		long threshold = Threshold(lpDIBBits, lWidth, lHeight);
		HGLOBAL	hGlobal = ::GlobalAlloc(GHND, lHeight*lWidth);
		LPSTR lpRecorder = (char*)::GlobalLock(hGlobal);
		::GlobalUnlock(hGlobal);
		memset(lpRecorder, 1, lHeight*lWidth);
		// 图像每行的字节数
		LONG lLineBytes;
		// 计算图像每行的字节数
		lLineBytes = WIDTHBYTES(lWidth * 8);
		PupilContour(lpRecorder, lWidth, lHeight, threshold, lpDIBBits);
		CList<PHTPoint, PHTPoint&>  PointListForPHT;
		FindPHTPoint(hGlobal, &PointListForPHT, lHeight, lWidth);//找到用于PHT变换的各个点；     
		if (PointListForPHT.IsEmpty())
		{
			AfxMessageBox("虹膜无法识别，退出");
			return;
		}
		CIRCLE InnerCircle = PHT(&PointListForPHT);
		PointListForPHT.RemoveAll();
		CIRCLE Outer = OuterCircle(lpDIBBits, lWidth, lHeight, InnerCircle);
		::GlobalFree(hGlobal);
		const long RectWidth = 512;
		const long RectHeight = 128;
		HDIB hDIB = TurnToRect(InnerCircle, Outer, lpDIB, RectWidth, RectHeight);
		LOGBin(hDIB);
		Morphological(hDIB);
		int tab = 0;
		PointInformation pointInfor[255];
		MarkthePoint(hDIB, pointInfor, tab);
		CharacterVector CharaV1[Character_length], CharaV2[Character_length];
		GetCharacterVector(pointInfor, tab, CharaV1, Character_length);
		float lamda=0, tmp=0;
		FILE *fp = NULL;
		fp = fopen("虹膜特征数据库.txt", "r");
		if (fp == NULL){ MessageBox(_T("虹膜特征数据库为空")); return; }
		while (feof(fp)==0)
		{
			for (int i = 0; i < Character_length; i++)
			{
				if (fscanf(fp, "%4u %4u %4u %4u %4u %4u %4u\n", &(CharaV2[i].left), &(CharaV2[i].right), &(CharaV2[i].top),
					&(CharaV2[i].bottom), &(CharaV2[i].type), &(CharaV2[i].x), &(CharaV2[i].y)) == -1)
				{
					MessageBox(_T("虹膜特征数据库为空"));
					return;
				}
			}
			tmp = Compare(CharaV1, CharaV2, Character_length, Character_length);
			lamda = lamda>tmp ? lamda : tmp;
		}
		fclose(fp);
		//int posi=1;
		//float lamda,tmp;
		//CFile mFile(_T("特征数据.txt"), CFile::modeRead);
		//if (mFile.GetLength() < 1){ MessageBox(_T("虹膜特征数据库为空")); return; }
		//while (posi==1)
		//{
		//	for (int i = 0; i < Character_length; i++)
		//	{
		//		posi = mFile.Read(&(CharaV2[i].left), 1);
		//		mFile.Read(&(CharaV2[i].right), 1);
		//		mFile.Read(&(CharaV2[i].top), 1);
		//		mFile.Read(&(CharaV2[i].bottom), 1);
		//		mFile.Read(&(CharaV2[i].type), 1);
		//		mFile.Read(&(CharaV2[i].x), 1);
		//		mFile.Read(&(CharaV2[i].y), 1);
		//	}
		//	lamda = Compare(CharaV1, CharaV2, Character_length, Character_length);
		//	lamda = lamda > tmp ? lamda : tmp;
		//}
		//mFile.Close();
		CString string;
		if (lamda > 0.11)
			string.Format("存在此虹膜！最大匹配率%f", lamda);
		else
			string.Format("不存在此虹膜！最大匹配率%f", lamda);
		sta_compare->SetWindowText(string);
		OnDraw(&dc);
	}
}


void CIRISView::OnBnClickedButtonSave()
{
	CFileDialog dlg(FALSE,"bmp","*.bmp",OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
		NULL,this,sizeof(OPENFILENAME ));
   if(dlg.DoModal()==IDOK)
   {
		CIRISDoc * pdoc=GetDocument();
		pdoc->OnSaveTargetImage(dlg.GetPathName());
   }
}


void CIRISView::OnBnClickedButtonExit()
{
	ASSERT(AfxGetMainWnd() != NULL);
    AfxGetMainWnd()->SendMessage(WM_CLOSE);
}

//-------------操作函数-----------------------------

//主要功能显示处理之后的图像
void CIRISView::OnDraw(CDC *pDC)
{  
	CFormView::OnDraw(pDC);
	CIRISDoc* pDoc=GetDocument();
	ASSERT_VALID(pDoc);
	if(pDoc->m_FilePath!="")
	{
		//获取DIB
		HDIB hDIB=pDoc->GetHDIB();
		HDIB hDIBTarget=pDoc->GetHDIBTarget();
		//判断DIB是否为空
		if(hDIB!=NULL)
		{
			LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
			//获取DIB宽度
			int cxDIB=(int)::DIBWidth(lpDIB);
			//获取DIB高度
			int cyDIB=(int)::DIBHeight(lpDIB);
			::GlobalUnlock((HGLOBAL) hDIB);
			CRect rcDIB;
			rcDIB.top=rcDIB.left=0;
			rcDIB.right=cxDIB;
			rcDIB.bottom=cyDIB;
			CRichEditCtrl* ImageSource=(CRichEditCtrl*)GetDlgItem(IDC_IMAGE_SOURCE);
			CRect  rcDest;
			ImageSource->GetRect(rcDest);
			if((rcDest.top-rcDest.bottom)<cyDIB||((rcDest.right-rcDest.left)<cxDIB))
			{
				ImageSource->SetRect(rcDIB);
				rcDest=rcDIB;
			}
			CDC * pDC=ImageSource->GetDC();
			ImageSource->Invalidate();
			ImageSource->UpdateWindow();
			//输出DIB
			::PaintDIB(pDC->m_hDC,&rcDest,pDoc->GetHDIB(),&rcDIB,pDoc->GetDocPalette());
			ReleaseDC(pDC);
			//Sleep(12000);
		}
	}
	/*
	HDIB hDIB=pDoc->GetHDIBTarget();
	// 判断DIB是否为空
	if(hDIB!=NULL)
	{
		LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
		// 获取DIB宽度
		int cxDIB=(int)::DIBWidth(lpDIB);
		// 获取DIB高度
		int cyDIB=(int) ::DIBHeight(lpDIB);
		::GlobalUnlock((HGLOBAL)hDIB);
		CRect rcDIB;
		rcDIB.top=rcDIB.left=0;
		rcDIB.right=cxDIB;
		rcDIB.bottom=cyDIB;
		CRichEditCtrl* ImageTarget=(CRichEditCtrl*)GetDlgItem(IDC_IMAGE_TARGET);
        CComboBox * SingleStepComb=(CComboBox*)GetDlgItem(IDC_COMBO_SINGLESTEP);
	    int a=SingleStepComb->GetCurSel();
		CRect  rcDest;
		ImageTarget->GetRect(rcDest);
		//对于归一化图形显示的特殊处理;因为此时图像过长，故压缩显示
		if(a==3||a==4)
		{
			rcDest.bottom=int (cyDIB*(float)rcDest.Width()/(float)cxDIB);
			ImageTarget->SetRect(rcDest);
		}
		else
		{
			if((rcDest.top-rcDest.bottom)<cyDIB||((rcDest.right-rcDest.left)<cxDIB))
			{
				ImageTarget->SetRect(rcDIB);
				rcDest=rcDIB;
			}
		}
		CDC * pDC=ImageTarget->GetDC();
		ImageTarget->Invalidate();
		ImageTarget->UpdateWindow();
		// 输出DIB
		::PaintDIB(pDC->m_hDC,&rcDest,pDoc->GetHDIBTarget(),&rcDIB,pDoc->GetDocPaletteTarget());
		ReleaseDC(pDC);
        //Sleep(12000);
	   }
	   */
}

//---------提取内边缘---------
void CIRISView::InnerEdge()
{
	LPSTR lpDIB;
	// 指向DIB象素指针
	LPSTR lpDIBBits;
	// 锁定DIB
	CIRISDoc * pDoc=GetDocument();
	lpDIB=(LPSTR)::GlobalLock((HGLOBAL) pDoc->GetHDIB());
	// 找到DIB图像象素起始位置
	lpDIBBits=::FindDIBBits(lpDIB);
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
	const long lWidth=::DIBWidth(lpDIB);
	const long lHeight=::DIBHeight(lpDIB);
	//建立存储位图灰度的数组
	long threshold=Threshold(lpDIBBits,lWidth,lHeight);      
	HGLOBAL hGlobal=::GlobalAlloc(GHND,lHeight*lWidth);
	LPSTR lpRecorder=(char *)::GlobalLock(hGlobal);
	::GlobalUnlock(hGlobal);
	memset(lpRecorder,1,lHeight*lWidth);  
	//图像每行的字节数
	LONG lLineBytes;
	// 计算图像每行的字节数
	lLineBytes=WIDTHBYTES(lWidth*8);
	PupilContour(lpRecorder,lWidth,lHeight,threshold,lpDIBBits);
	CList<PHTPoint, PHTPoint&>  PointListForPHT;
	FindPHTPoint(hGlobal,&PointListForPHT,lHeight,lWidth);//找到用于PHT变换的各个点；
	if(PointListForPHT.IsEmpty())
	{
		AfxMessageBox("不是虹膜图像或者图像过于模糊无法辨别！");
		CComboBox * SingleStepComb=(CComboBox*)GetDlgItem(IDC_COMBO_SINGLESTEP);
		SingleStepComb->SetCurSel(0);
		return;
	}
	CIRCLE InnerCircle=PHT(&PointListForPHT);//PHT变换；
	pDoc->CopyToTarget(pDoc->GetHDIB());
	lpDIB=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIBTarget());
	::GlobalFree(hGlobal);
	// 找到DIB图像象素起始位置
	lpDIBBits=::FindDIBBits(lpDIB);
	::GlobalUnlock((HGLOBAL)pDoc->GetHDIBTarget());
	for(long i=0;i<lHeight;i++)
	{
		for (long j=0;j<lWidth;j++)
		{   
			if(abs(pow((double)(j-InnerCircle.x),2)+pow((double)(i-InnerCircle.y),2)-
				pow((double)InnerCircle.r,2))<abs((j-InnerCircle.x))+abs((i-InnerCircle.y)))
			  //考虑到数字化误差，将差值限定在一定范围内
					*((unsigned char *)(lpDIBBits+lLineBytes*i+j))=255;
		}
	}
}
//建立灰度直方图，找到阈值
//lpDIBBitsDIB图像象素起始位置
//lWidth宽lHeight高
long CIRISView::Threshold(LPSTR lpDIBBits,long lWidth,long lHeight)
{
    long Count[256];
    // 重置计数为0
	for (int i = 0; i < 256; i ++)
	{// 清零
		Count[i] = 0;
	}
	// 图像每行的字节数
	long lLineBytes;
	// 计算图像每行的字节数
	lLineBytes = WIDTHBYTES(lWidth * 8);
	// 计算各个灰度值的计数
	LPSTR  lpSrc;
	long i;
	for(i=0;i<lHeight;i++)
	{
		for(long j=0;j<lWidth;j ++)
		{
			lpSrc=lpDIBBits+lLineBytes*i+j;
			// 计数加1
			Count[*((unsigned char *)(lpSrc))]+=1;
		}
	}
	//对数组进行平滑运算
    Count[0]=0;
	Count[1]=(Count[1]+Count[0])/2;
	for(i=3;i<255;i++)
	{
		Count[i]=(Count[i]+Count[i-1]+Count[i+1])/3;
	}
	//对数组进行一阶差分
	long difference[256];
	difference[0]=0;
	for(int i=1;i<256;i++)
		difference[i]=Count[i]-Count[i-1];
	//自动寻找分割点
	unsigned char  threshold=0;//阈值点
	long max=Count[0];
	for(int i=1;i<256;i++)
	{
		if(max<Count[i])
			max=Count[i];
		 //为了确保准确性，规定阈值选取的峰谷点应小于峰值的最高点的1/2,且最高值应大于200象素。
		if((difference[i]<0)&&(difference[i+1]>=0)&&(max/2>Count[i+1])&&max>200)
		{
			threshold=(unsigned char)i+1;
			break;
		}
	 }
	 return threshold;
}
//瞳孔内部轮廓
//lpRecorder令其指向内存块的起始处
//lpDIBBitsDIB图像象素起始位置
//lWidth宽lHeight高
void CIRISView::PupilContour(LPSTR lpRecorder,long lWidth,long lHeight,long threshold,LPSTR lpDIBBits)
{
	//图像每行的字节数
	LONG lLineBytes;
    LPSTR  lpSrc;
	// 计算图像每行的字节数
	lLineBytes=WIDTHBYTES(lWidth*8);
	for(long i=1;i<lHeight-1;i++)
	{
		for(long j=1;j<lWidth-1;j++)
		{
			lpSrc=lpDIBBits+lLineBytes*i+j;
			//该点的4个邻域
			LPSTR lpSrc_right=lpDIBBits+lLineBytes*i+j+1;
            LPSTR lpSrc_left=lpDIBBits+lLineBytes*i+j-1;
			LPSTR lpSrc_top=lpDIBBits+lLineBytes*(i+1)+j;
			LPSTR lpSrc_bottom=lpDIBBits+lLineBytes*(i-1)+j;
			if(unsigned char (*lpSrc)<threshold)
			{
				if(!((unsigned char (*lpSrc_right)<threshold)&&(unsigned char(*lpSrc_left)<threshold)
					&&(unsigned char(*lpSrc_top)<threshold)&&(unsigned char(*lpSrc_bottom)<threshold)))//边界点
						*(lpRecorder+lLineBytes*i+j)=0;
			}
		 }
	}
    for(long i=1;i<lHeight-1;i++)//去除边缘毛刺；
	{   
		for(long j=1;j<lWidth-1;j++)
	    {
			lpSrc=lpRecorder+lLineBytes*i+j;
	        if(*lpSrc==(unsigned char)0)
			{
				char a1=*(lpRecorder+lLineBytes*i+j+1);
				char a2=*(lpRecorder+lLineBytes*i+j-1);
				char a3=*(lpRecorder+lLineBytes*(i+1)+j);
				char a4=*(lpRecorder+lLineBytes*(i+1)+j-1);
				char a5=*(lpRecorder+lLineBytes*(i+1)+j+1);
				char a6=*(lpRecorder+lLineBytes*(i-1)+j-1);
				char a8=*(lpRecorder+lLineBytes*(i-1)+j);
				char a7=*(lpRecorder+lLineBytes*(i-1)+j+1);
				unsigned char a=a1+a2+a3+a4+a5+a6+a7+a8;
				if(a>6)
					*(lpRecorder+lLineBytes*i+j)=1;
			}
		 }
		
	}
	for(long i=lHeight-2;i>0;i--)//去除边缘毛刺；
	{   
		 for(long j=lWidth-2;j>0;j--)
	     {
			lpSrc=lpRecorder+lLineBytes*i+j;
			if(*lpSrc==0)
			{
				char a1=*(lpRecorder+lLineBytes*i+j+1);
				char a2=*(lpRecorder+lLineBytes*i+j-1);
				char a3=*(lpRecorder+lLineBytes*(i+1)+j);
				char a4=*(lpRecorder+lLineBytes*(i+1)+j-1);
				char a5=*(lpRecorder+lLineBytes*(i+1)+j+1);
				char a6=*(lpRecorder+lLineBytes*(i-1)+j-1);
				char a7=*(lpRecorder+lLineBytes*(i-1)+j+1);
				char a8=*(lpRecorder+lLineBytes*(i-1)+j);
				unsigned char a=a1+a2+a3+a4+a5+a6+a7+a8;
				if(a>6)
					*lpSrc=(unsigned char)1;
			}
		 }
	}
}
//用来寻找用于PHT变换的点组
//SourceImage指向记录图像,边界点用0表示,其他点用1表示
//PHTlist存储PHT变换点的数组
void CIRISView::FindPHTPoint(HGLOBAL hSourceImage,CList<PHTPoint,PHTPoint&> *PHTlist,long lHeight,long lWidth)
{
	//是否扫描到一个边界点
	bool bFindPoint;
   //是否跟踪到了一条线的末端；
	bool MeetTheEndOfLine;
    bool bFindStartPoint;
	//起始边界点与当前边界点
	CPoint StartPoint,CurrentPoint;
	//八个方向和起始扫描方向
	int Direction[8][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0}};
	int BeginDirect;
	LPSTR SourceImage=(char *)::GlobalLock(hSourceImage);
    ::GlobalUnlock(hSourceImage);
	int LineNumber=0;//用于指定跟踪的线段编号；
	for(long j=1;j<lHeight-1;j++)//关注i、j与点x、y之间的关系
	{
		for(long i=1;i<lWidth-1;i++)
		{
			//先找到最左上方的边界点
	        bFindStartPoint=false;//区分两种情况:1曲线又回到了起点
			MeetTheEndOfLine=false;//  2跟踪到一条直线的末端。
			int PointNumberOfThisType=0;//线段上的点的数目。
			if(*((unsigned char *)(SourceImage+lWidth*j+i))==0)
			{ 
			   StartPoint=CPoint(i,j);
               //由于起始点是在左下方，故起始扫描沿左上方向
	           BeginDirect=0;
	           //跟踪边界
               //从初始点开始扫描
	           CurrentPoint.x=StartPoint.x;
	           CurrentPoint.y=StartPoint.y;
	           PHTPoint PhtPoint; 
			   PhtPoint.Point=StartPoint;
			   PhtPoint.LineNumber=LineNumber;
			   PHTlist->AddTail(PhtPoint);
               PointNumberOfThisType=1;
			   int pixel_length=0;//此点是用来确定象素之间距，根据间距来确定选取PHT变换的点；
               while(!MeetTheEndOfLine&&!bFindStartPoint)
	           {
					bFindPoint=false;
					int TurnNumber=0;//统计旋转次数的变量；如果是一条线段的端点，
				                 //则因在寻找过程中已经将跟踪过的点清零，此点为一孤立点；
					while(!bFindPoint)
					{   
						//沿扫描方向查看一个像素
						unsigned char a=*(SourceImage+(CurrentPoint.y+
							Direction[BeginDirect][1])*lWidth+CurrentPoint.x+Direction[BeginDirect][0]);
						if((CurrentPoint.y + Direction[BeginDirect][1]==StartPoint.y)&&(CurrentPoint.x
							+Direction[BeginDirect][0]== StartPoint.x))
						{
							bFindStartPoint=true;
							CurrentPoint.x=0;
							CurrentPoint.y=0;
							LineNumber++;
							break;
						}
						if(a==0)
						{  
							pixel_length++;
							//此部分是用于寻找PHT变换的各个点的
							if(pixel_length==distant_used_for_PHT)
							{
								pixel_length=0;
								PhtPoint.Point=CurrentPoint;
								PhtPoint.LineNumber=LineNumber;
								PHTlist->AddTail(PhtPoint);
								PointNumberOfThisType++;
							}
							bFindPoint = true;
							//找到下一点后将该点标志
							*(SourceImage+(CurrentPoint.y)*lWidth+CurrentPoint.x)=1;
							CurrentPoint.y=CurrentPoint.y+Direction[BeginDirect][1];
							CurrentPoint.x=CurrentPoint.x+Direction[BeginDirect][0];
							BeginDirect--;
							if(BeginDirect==-1)
								BeginDirect=7;
							BeginDirect--;
							if(BeginDirect==-1)
								BeginDirect=7;
						}
						else
						{
							//扫描方向顺时针旋转一格
							BeginDirect++;
							if(BeginDirect==8)
								BeginDirect=0;
							TurnNumber++;
							if(TurnNumber==8)
							{  
								MeetTheEndOfLine=TRUE;
								LineNumber+=1;
								*(SourceImage+(CurrentPoint.y)*lWidth+CurrentPoint.x)=1;
								bFindPoint=true;
							}
			  
						}
					}//while(!bFindPoint)
				}//while(!MeetTheEndOfLine&&!bFindStartPoint)
				if(MeetTheEndOfLine||PointNumberOfThisType<4)//排除上述取圆规则误取的点集；
				{
					for(i=0;i<PointNumberOfThisType;i++)
						PHTlist->RemoveTail();
					LineNumber--;
				}
			}//if

		}//for
	}//for
	return ;
}
//内部圆心的确定
//PHTlist存储PHT变换点的数组
CIRCLE CIRISView::PHT(CList<PHTPoint, PHTPoint&> * PHTlist)
{
	long a=PHTlist->GetCount();
	CList<PHTPointGROUP,PHTPointGROUP&> PHTGroupList;//储存用于PHT变换的点组的列表
	POSITION pos=PHTlist->GetHeadPosition();
	POSITION pos_begin=pos;
	POSITION pos_end;
	PHTPoint point=PHTlist->GetNext(pos);
	PHTPointGROUP PHTGroup;
	int UsefulPointNumber=1;
	int LineNumber=point.LineNumber;
	bool FinishCircle=false;	
	while(!FinishCircle)
	{ 
		bool MeetTheEnd=false;
		do
		{
			point=PHTlist->GetNext(pos);
			UsefulPointNumber++;
			if(pos==NULL)
			{
				MeetTheEnd=true;
				FinishCircle=true;
			}
			else
			{  
				if(point.LineNumber!=LineNumber) 
				{  
					LineNumber=point.LineNumber;
					MeetTheEnd=true;
					UsefulPointNumber--;
					PHTlist->GetPrev(pos);
				}
			}//else
		}while(!MeetTheEnd);
		pos_end=pos;
		int Step=UsefulPointNumber/3;
		pos=pos_begin;
		for(int i=0;i<UsefulPointNumber;i++)
		{
			PHTPoint point;
			point=PHTlist->GetNext(pos);
		}
		int i;
		for(i=0;i<UsefulPointNumber;i++)
		{
			PHTPoint point;
			point=PHTlist->GetAt(pos_begin);
			pos=pos_begin;
			for(int j=0;j<i;j++)
				point=PHTlist->GetNext(pos);
		    PHTGroup.a=point.Point;
            for(int j=0;j<Step;j++)
			{
				point=PHTlist->GetNext(pos);
				if(pos==NULL||pos==pos_end)
					pos=pos_begin;
			}
			 
            PHTGroup.b=point.Point;
			for(int j=0;j<Step;j++)
			{
				point=PHTlist->GetNext(pos);
				if(pos==NULL||pos==pos_end)
					pos=pos_begin;
			}
			PHTGroup.c=point.Point;
			PHTGroupList.AddTail(PHTGroup);
		}
		UsefulPointNumber=1;
		pos=pos_end;
	}//while(!FinishCircle)
	pos=PHTGroupList.GetHeadPosition();
	a=PHTGroupList.GetCount();
	CArray<CIRCLE,CIRCLE&> circle;
	circle.SetSize(a);
	int CircleNumber=0;
	while(pos!=NULL)
	{
		PHTPointGROUP PHTGroup=PHTGroupList.GetNext(pos);
		if((PHTGroup.a.y-PHTGroup.b.y)==0||(PHTGroup.b.y-PHTGroup.c.y)==0)
			continue;
		//排除计算式分母为零的点组
		float k1=-(float)(PHTGroup.a.x-PHTGroup.b.x)/(float)(PHTGroup.a.y-PHTGroup.b.y);
		float k2=-(float)(PHTGroup.b.x-PHTGroup.c.x)/(float)(PHTGroup.b.y-PHTGroup.c.y);
		float d1=((PHTGroup.a.y+PHTGroup.b.y)-k1*(PHTGroup.a.x+PHTGroup.b.x))/2.0;
		float d2=((PHTGroup.b.y+PHTGroup.c.y)-k2*(PHTGroup.b.x+PHTGroup.c.x))/2.0;
		if(k1==k2)
			continue;
		float ac=-(d1-d2)/(k1-k2);
		float bc=k1*ac+d1;
		float  rc=sqrt(pow((PHTGroup.a.x-ac),2)+pow((PHTGroup.a.y-bc),2));
		circle[CircleNumber].x=(int)(ac+0.5);
		circle[CircleNumber].y=(int)(bc+0.5);
		circle[CircleNumber].r=(int)(rc+0.5);
        CircleNumber++;
	}//while
	CArray<int,int> pointsum;
	pointsum.SetSize(CircleNumber);
	int i;
	for(i=0;i<CircleNumber;i++)
		pointsum[i]=0;
	for(i=0;i<CircleNumber;i++)
	{
		for (int j=0;j<CircleNumber;j++)
		{
			if(distance(circle[i],circle[j])<2.5)
				pointsum[i]+=1;
		}
	}
	int max=0;
	for(i=1;i<CircleNumber;i++)
	{
		if (pointsum[i-1]<pointsum[i])
			max=i;
	}
	CIRCLE MaxCircle;
	MaxCircle.x=0;
	MaxCircle.y=0;
	MaxCircle.r=0;
	int counter=0;
	for(i=max;i<CircleNumber;i++)
	{
		if(pointsum[i]==pointsum[max])
		{
			MaxCircle.x+=circle[i].x;
			MaxCircle.y+=circle[i].y;
			MaxCircle.r+=circle[i].r;
			counter++;
		}
	}
	MaxCircle.x=(float)MaxCircle.x/(float)counter+0.5;
	MaxCircle.y=(float)MaxCircle.y/(float)counter+0.5;
	MaxCircle.r=(float)MaxCircle.r/(float)counter+0.5;
	return MaxCircle;
}

//---------提取外边缘---------
void CIRISView::OuterEdge()
{
	LPSTR lpDIB;
	// 指向DIB象素指针
	LPSTR lpDIBBits;
	// 锁定DIB
	CIRISDoc * pDoc=GetDocument();
	lpDIB=(LPSTR)::GlobalLock((HGLOBAL) pDoc->GetHDIB());
	// 找到DIB图像象素起始位置
	lpDIBBits=::FindDIBBits(lpDIB);
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
	const long lWidth=::DIBWidth(lpDIB);
	const long lHeight=::DIBHeight(lpDIB);
	//建立存储位图灰度的数组
	long threshold=Threshold(lpDIBBits,lWidth,lHeight);      
	HGLOBAL hGlobal=::GlobalAlloc(GHND,lHeight*lWidth);
	LPSTR lpRecorder=(char *)::GlobalLock(hGlobal);
	::GlobalUnlock(hGlobal);
	memset(lpRecorder,1,lHeight*lWidth);  
	//图像每行的字节数
	LONG lLineBytes;
	// 计算图像每行的字节数
	lLineBytes=WIDTHBYTES(lWidth*8);
	PupilContour(lpRecorder,lWidth,lHeight,threshold,lpDIBBits);
	CList<PHTPoint, PHTPoint&>  PointListForPHT;
	FindPHTPoint(hGlobal,&PointListForPHT,lHeight,lWidth);//找到用于PHT变换的各个点；
	if(PointListForPHT.IsEmpty())
	{
		AfxMessageBox("不是虹膜图像或者图像过于模糊无法辨别！");
		CComboBox * SingleStepComb=(CComboBox*)GetDlgItem(IDC_COMBO_SINGLESTEP);
		SingleStepComb->SetCurSel(0);
		return;
	}
	CIRCLE InnerCircle=PHT(&PointListForPHT);//PHT变换
	CIRCLE Outer=OuterCircle(lpDIBBits,lWidth,lHeight,InnerCircle);//外界圆的确定
	pDoc->CopyToTarget(pDoc->GetHDIB());
	lpDIB=(LPSTR)::GlobalLock((HGLOBAL)pDoc->GetHDIBTarget());
	::GlobalFree(hGlobal);
	// 找到DIB图像象素起始位置
	lpDIBBits=::FindDIBBits(lpDIB);
	::GlobalUnlock((HGLOBAL)pDoc->GetHDIBTarget());
	for(long i=0;i<lHeight;i++)
	{
		for (long j=0;j<lWidth;j++)
		{   
			if(abs(pow((double)(j-Outer.x),2)+pow((double)(i-Outer.y),2)-
				pow((double)Outer.r,2))<abs((j-Outer.x))+abs((i-Outer.y)))
			  //考虑到数字化误差，将差值限定在一定范围内
					*((unsigned char *)(lpDIBBits+lLineBytes*i+j))=255;
		}
	}
}
//找到外边界
//lpDIBBitsDIB图像象素起始位置
//lWidth宽lHeight高
//InnerCircle内接圆
CIRCLE CIRISView::OuterCircle(LPSTR lpDIBBits,long lWidth,long lHeight,CIRCLE InnerCircle)
{ 
    CIRCLE MaxCircle,MaxCircle1;
	//最终确定的圆
	MaxCircle.r=0;
	MaxCircle.x=0;
	MaxCircle.y=0;
	//初步确定的圆
	MaxCircle1.x=0;
	MaxCircle1.y=0;
	MaxCircle1.r=0;
	float max=0;
	//图像每行的字节数
	LONG lLineBytes;
	const int r_step=4;//每次搜索的半径步长即△t
	const int angle_step=1;//每次搜索的角度步长即△θ
	const int centre_range=5;//圆心变动范围
	//计算图像每行的字节数
	lLineBytes=WIDTHBYTES(lWidth*8);
	for(long l=-centre_range;l<=centre_range;l++)//求外圆
	{
		for(long k=-centre_range;k<=centre_range;k++)
		{
			int from=InnerCircle.r+4*centre_range;//从外圆开始搜索搜索起始位置
			int to=min(from+5*InnerCircle.r,min(InnerCircle.x+k,lWidth-InnerCircle.x-k));//搜索终止位置；
			int Array_Number=(to-from)/r_step;
			float * array_for_circle_integration=new float[Array_Number];//用于记录每次环量积分的结果
			float * convolution=new float[Array_Number];//用于记录环量积分平滑值的数组
			for(long m=0;m<Array_Number;m++)
			{
				array_for_circle_integration[m]=0;
				convolution[m]=0;
			}
			for(long r=from;r<to-r_step;r=r+r_step)//求环量积分；
			{    
				int sum_number=0;
			    for(int i=-r_step/2;i<r_step/2;i++)//虹膜左半部分；
				{	
					for(float angle=30;angle>-30;angle=angle-angle_step)
					{   
						if(InnerCircle.y+l+(long)((r+i)*sin(angle/360*2*pi))<0||
							InnerCircle.y+l+(long)((r+i)*sin(angle/360*2*pi))>lHeight) 
							continue;
						unsigned char w=(unsigned char)*(lpDIBBits+(InnerCircle.y+l+
							(long)((r+i)*sin(angle/360*2*pi)))*lLineBytes+k+InnerCircle.x+
							(long)((r+i)*cos(angle/360*2*pi)));
						array_for_circle_integration[(r-from)/r_step]+=w;  
						sum_number++;
					}
				}
				for(int i=-r_step/2;i<r_step/2;i++)//虹膜右半部分
				{
					for(float angle=150;angle<210;angle=angle+angle_step)
					{    
						if(InnerCircle.y+l+(long)((r+i)*sin(angle/360*2*pi))<0||
							InnerCircle.y+l+(long)((r+i)*sin(angle/360*2*pi))>lHeight) 
							continue;
						array_for_circle_integration[(r-from)/r_step]+=(unsigned char)*(lpDIBBits+
							(InnerCircle.y+l+(long)((r+i)*sin(angle/360*2*pi)))*lLineBytes+k+
							InnerCircle.x+(long)((r+i)*cos(angle/360*2*pi)));
						sum_number++;
					}
				}
				array_for_circle_integration[(r-from)/r_step]=array_for_circle_integration[(r-from)/r_step]/sum_number;
			 }
			convolution[0]=(8*array_for_circle_integration[0]+array_for_circle_integration[1])/9.0;
			for(long r=from+r_step;r<to-2*r_step;r=r+r_step)//求卷积
			{    
				convolution[(r-from)/r_step]=(8*array_for_circle_integration[(r-from)/r_step]
				+array_for_circle_integration[(r-from-r_step)/r_step]+
				 array_for_circle_integration[(r-from+r_step)/r_step])/10.0;
			}
			convolution[(to-r_step-from)/r_step]=(8*array_for_circle_integration[(to-r_step-from)/r_step]
				+array_for_circle_integration[(to-2*r_step-from)/r_step])/9.0;
		     for(long i=1;i<(to-from-r_step)/r_step;i++)//寻找环量积分的最大值
			 {   
				float a=convolution[i]-convolution[i-1];
				if(a>max)
				{      
					max=a;
					MaxCircle1.r=from+(i-1)*r_step;
					MaxCircle1.x=InnerCircle.x+k;
					MaxCircle1.y=InnerCircle.y+l;
				}
			}
         delete[] array_for_circle_integration;
	     delete[] convolution;
		}//for
	}//for
	//return MaxCircle1;
	 //一下内容是是以一定步长初步求得最大圆之后，再在每一个象素内精细求解
	long * TheMax=new long[r_step];
	int sum_number=0;
	int i=0;
	for(long  r=MaxCircle1.r-r_step/2+1;r<MaxCircle1.r+r_step/2;r++)//环量积分
	{  
		for(float angle=30;angle>-30;angle=angle-angle_step)//左半部分
		{
			if(MaxCircle1.y+(long)(r*sin(angle/360*2*pi))<0||
				MaxCircle1.y+(long)(r*sin(angle/360*2*pi))>lHeight) 
					continue;
			TheMax[i]+=*(lpDIBBits+(MaxCircle1.y+(long)(r*sin(angle/360*2*pi)))*lLineBytes+
				MaxCircle1.x+(long)(r*cos(angle/360*2*pi)));        
			sum_number++;
		}
		for(float angle=150;angle<210;angle=angle+angle_step)//右半部分
		{
			if(MaxCircle1.y+(long)(r*sin(angle/360*2*pi))<0||
				MaxCircle1.y+(long)(r*sin(angle/360*2*pi))>lHeight) 
					continue;
			TheMax[i]+=*(lpDIBBits+(MaxCircle1.y+(long)(r*sin(angle/360*2*pi)))*lLineBytes+
				MaxCircle1.x+(long)(r*cos(angle/360*2*pi)));  
			sum_number++;
		}
		TheMax[i]=TheMax[i]/sum_number;
		i++;
	}
	long differ=0;//寻找最大值即使求最大的MAX
	for(int j=1;j<=i;j++)
	{   
		if(abs(TheMax[j]-TheMax[j-1])>differ)
		{
			differ=TheMax[j]-TheMax[j-1];
			MaxCircle.x=MaxCircle1.x;
			MaxCircle.y=MaxCircle1.y;
			MaxCircle.r=MaxCircle1.r-r_step/2+1+j;
		}
	}
	delete[] TheMax;
	return MaxCircle;
}

//---------归一化和展开---------
void CIRISView::NormalRect()
{
	LPSTR lpDIB;
	// 指向DIB象素指针
	LPSTR lpDIBBits;
	// 锁定DIB
	CIRISDoc * pDoc=GetDocument();
	lpDIB=(LPSTR)::GlobalLock((HGLOBAL) pDoc->GetHDIB());
	// 找到DIB图像象素起始位置
	lpDIBBits=::FindDIBBits(lpDIB);
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
	const long lWidth=::DIBWidth(lpDIB);
	const long lHeight=::DIBHeight(lpDIB);
	//建立存储位图灰度的数组
	long threshold=Threshold(lpDIBBits,lWidth,lHeight);      
	HGLOBAL hGlobal=::GlobalAlloc(GHND,lHeight*lWidth);
	LPSTR lpRecorder=(char *)::GlobalLock(hGlobal);
	::GlobalUnlock(hGlobal);
	memset(lpRecorder,1,lHeight*lWidth);  
	//图像每行的字节数
	LONG lLineBytes;
	// 计算图像每行的字节数
	lLineBytes=WIDTHBYTES(lWidth*8);
	PupilContour(lpRecorder,lWidth,lHeight,threshold,lpDIBBits);
	CList<PHTPoint, PHTPoint&>  PointListForPHT;
	FindPHTPoint(hGlobal,&PointListForPHT,lHeight,lWidth);//找到用于PHT变换的各个点；
	if(PointListForPHT.IsEmpty())
	{
		AfxMessageBox("不是虹膜图像或者图像过于模糊无法辨别！");
		CComboBox * SingleStepComb=(CComboBox*)GetDlgItem(IDC_COMBO_SINGLESTEP);
		SingleStepComb->SetCurSel(0);
		return;
	}
	CIRCLE InnerCircle=PHT(&PointListForPHT);//PHT变换
	CIRCLE Outer=OuterCircle(lpDIBBits,lWidth,lHeight,InnerCircle);//外界圆的确定
	::GlobalFree(hGlobal);
	const long RectWidth=512;
	const long RectHeight=128;
	HDIB hDIB=TurnToRect(InnerCircle,Outer,lpDIB,RectWidth,RectHeight);
	pDoc->CopyToTarget(hDIB);
	::GlobalFree((HGLOBAL) hDIB);
}
//转为矩形
//Inner内圆
//Outer外圆
//RectWidth宽度
//RectHeight高度
HDIB CIRISView::TurnToRect(CIRCLE Inner, CIRCLE Outer,LPSTR lpDIB,long RectWidth,long RectHeight)
{
	long lWidth;
	long lHeight;
	LPBITMAPINFOHEADER lpbmi;
	LPSTR lpDIBBits,lpDst;
	LPSTR lpNewDIBBits,lpNewDIB;
	HDIB hDIB;
	float i,j;
	float i0,j0;
	long lLineBytes;
	long lNewLineBytes;
	lpDIBBits=::FindDIBBits(lpDIB);
	lWidth=::DIBWidth(lpDIB);
	lHeight=::DIBHeight(lpDIB);
    lLineBytes = WIDTHBYTES(lWidth * 8);
	lNewLineBytes= WIDTHBYTES(RectWidth * 8);
	hDIB=(HDIB)::GlobalAlloc(GHND,RectHeight*lNewLineBytes+*(LPDWORD)lpDIB+::PaletteSize(lpDIB));
	if(!hDIB)
	{ 
		AfxMessageBox("创建新内存失败!");
		return NULL;
	}
	lpNewDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
	memcpy(lpNewDIB,lpDIB,*(LPDWORD)lpDIB+::PaletteSize(lpDIB));
	lpbmi=(LPBITMAPINFOHEADER)lpNewDIB;
	lpbmi->biWidth=RectWidth;
	lpbmi->biHeight=RectHeight;
	::GlobalUnlock((HGLOBAL)hDIB);
	lpNewDIBBits=::FindDIBBits(lpNewDIB);
	if(Inner.x==Outer.x)//内圆圆心在x轴上；
	{ 
		for (i=0.0;i<RectWidth;i++)
		{
			int x1=Inner.x+Inner.r*cos((i/(RectWidth-1))*2*pi);
			int y1=Inner.y+Inner.r*sin((i/(RectWidth-1))*2*pi);
			float r0=sqrt(pow((double)(Inner.x-Outer.x),2)+pow((double)(Inner.y-Outer.y),2));
			float q1;
			if(i/RectWidth<=1/4)
				q1=(i/RectWidth)*2*pi+pi/2;
			else if(1/4<i/RectWidth<=1/2)
				q1=pi-(i/RectWidth)*2*pi+pi/2;
			else if(1/2<i/RectWidth<=3/4)
				q1=3/2*pi-(i/RectWidth)*2*pi;
			else 
				q1=(i/RectWidth)*2*pi-pi   ;
			float q2=asin((r0*sin(q1))/Outer.r);
			float Ia=sqrt(pow((double)r0,2)+pow((double)Outer.r,2)-2*r0*Outer.r*cos(pi-q1-q2));
			int x2=Inner.x+Ia*cos((i/(RectWidth-1))*2*pi);
			int y2=Inner.y+Ia*sin((i/(RectWidth-1))*2*pi);
            for(j=0.0;j<RectHeight;j++)
		    {      		 
				float lamuda=j/(RectHeight-1);
				i0=(1-lamuda)*x1+lamuda*x2;
				j0=(1-lamuda)*y1+lamuda*y2;
				lpDst=lpNewDIBBits+lNewLineBytes*((long)j)+(long)i;                 
				*lpDst=DLInsAlgorithm(lpDIB,i0,j0);
			}
		}
	}
	if(Inner.x<Outer.x&&Inner.y>=Outer.y)//内圆圆心在第二象限；
	{
		for (i=0.0;i<RectWidth;i++)
		{
			int x1=Inner.x+Inner.r*cos((i/(RectWidth-1))*2*pi);
			int y1=Inner.y+Inner.r*sin((i/(RectWidth-1))*2*pi);
			float q1=atan((double)abs((Inner.y-Outer.y)/(Inner.x-Outer.x)));
			float r0=sqrt(pow((double)(Inner.x-Outer.x),2)+pow((double)(Inner.y-Outer.y),2));
			float q=(i/(RectWidth-1))*2*pi+q1;
			if(q>pi)
				q=2*pi-q;
			if(q<0)
			q=-q;
			float q2=asin(r0*sin(q)/Outer.r);
			float Ia=sqrt(pow((double)r0,2)+pow((double)Outer.r,2)-2*r0*Outer.r*cos(pi-q-q2));
			int x2=Inner.x+Ia*cos((i/(RectWidth-1))*2*pi);
			int y2=Inner.y+Ia*sin((i/(RectWidth-1))*2*pi);
			for(j=0.0;j<RectHeight;j++) 
		    {   
				float lamuda=j/(RectHeight-1);
				i0=(1-lamuda)*x1+lamuda*x2;
				j0=(1-lamuda)*y1+lamuda*y2;
				lpDst=lpNewDIBBits+lNewLineBytes*((long)j)+(long)i;
				*lpDst=DLInsAlgorithm(lpDIB,i0,j0); 
			}
		}
	}
	if(Inner.x>Outer.x&&Inner.y>=Outer.y)//内圆圆心在第一象限；
	{  
		for (i=0.0;i<RectWidth;i++)
		{       
			int x1=Inner.x+Inner.r*cos((i/(RectWidth-1))*2*pi);
			int y1=Inner.y+Inner.r*sin((i/(RectWidth-1))*2*pi);
			float q1=atan((double)abs((Inner.y-Outer.y)/(Inner.x-Outer.x)));
			float r0=sqrt(pow((double)(Inner.x-Outer.x),2)+pow((double)(Inner.y-Outer.y),2));
			float q=(i/(RectWidth-1))*2*pi+q1;
			if(q<0)
				q=-q; 
			float q2=asin(r0*sin(q)/Outer.r);
			float Ia=sqrt(pow((double)r0,2)+pow((double)Outer.r,2)-2*r0*Outer.r*cos(pi-q2-q));
			int x2=Inner.x+Ia*cos((i/(RectWidth-1))*2*pi);
			int y2=Inner.y+Ia*sin((i/(RectWidth-1))*2*pi);
			for(j=0.0;j<RectHeight;j++)
			{      
				float lamuda=j/(RectHeight-1);
				i0=(1-lamuda)*x1+lamuda*x2;
				j0=(1-lamuda)*y1+lamuda*y2;
				lpDst=lpNewDIBBits+lNewLineBytes*((long)j)+(long)i;
				*lpDst=DLInsAlgorithm(lpDIB,i0,j0);
			}
		}
	}
	if(Inner.x<Outer.x&&Inner.y<=Outer.y)//内圆圆心在第三象限；
	{
		for (i=0.0;i<RectWidth;i++)
		{
			int x1=Inner.x+Inner.r*cos((i/(RectWidth-1))*2*pi);
			int y1=Inner.y+Inner.r*sin((i/(RectWidth-1))*2*pi);
			float q1=atan((double)abs((Inner.y-Outer.y)/(Inner.x-Outer.x)));
			float r0=sqrt(pow((double)(Inner.x-Outer.x),2)+pow((double)(Inner.y-Outer.y),2));
			float q=(i/(RectWidth-1))*2*pi-q1;
			if(q<0)
				q=-q;
			if(q>pi)
				q=2*pi-q;
			float q2=asin(r0*sin(q)/Outer.r);
			float Ia=sqrt(pow((double)r0,2)+pow((double)Outer.r,2)-2*r0*Outer.r*cos(pi-q-q2));
			int x2=Inner.x+Ia*cos((i/(RectWidth-1))*2*pi);
			int y2=Inner.y+Ia*sin((i/(RectWidth-1))*2*pi);
			for(j=0.0;j<RectHeight;j++) 
			{    
				float lamuda=j/(RectHeight-1);
				i0=(1-lamuda)*x1+lamuda*x2;
				j0=(1-lamuda)*y1+lamuda*y2;
				lpDst=lpNewDIBBits+lNewLineBytes*((long)j)+(long)i;
				*lpDst=DLInsAlgorithm(lpDIB,i0,j0);	       
			}
		}
	
	}
	if(Inner.x>Outer.x&&Inner.y<=Outer.y)//内圆圆心在第四象限；
	{
		for (i=0.0;i<RectWidth;i++)
		{
			int x1=Inner.x+Inner.r*cos((i/(RectWidth-1))*2*pi);
			int y1=Inner.y+Inner.r*sin((i/(RectWidth-1))*2*pi); 
			float q1=atan((double)abs((Inner.y-Outer.y)/(Inner.x-Outer.x)));
			float r0=sqrt(pow((double)(Inner.x-Outer.x),2)+pow((double)(Inner.y-Outer.y),2));
			float q=pi-( i/(RectWidth-1))*2*pi-q1;
			if(q<0)
				q=-q;
			float q2=asin(r0*sin(q)/Outer.r);
			float Ia=sqrt(pow((double)r0,2)+pow((double)Outer.r,2)-2*r0*Outer.r*cos(pi-q-q2));
			int x2=Inner.x+Ia*cos((i/(RectWidth-1))*2*pi);
			int y2=Inner.y+Ia*sin((i/(RectWidth-1))*2*pi);
		    for(j=0.0;j<RectHeight;j++)
		    {   
				float lamuda=j/(RectHeight-1);
				i0=(1-lamuda)*x1+lamuda*x2;
				j0=(1-lamuda)*y1+lamuda*y2;
				lpDst=lpNewDIBBits+lNewLineBytes*((long)j)+(long)i;
				*lpDst=DLInsAlgorithm(lpDIB,i0,j0);   
			}
		}
	}
	return hDIB;
}
//双线性内插法
unsigned char CIRISView::DLInsAlgorithm(LPSTR lpDIB,float x,float y)
{ 
	LPSTR lpDIBBits;
	long lWidth,lHeight;
	long i1,i2;
	long j1,j2;
	unsigned char f1,f2,f3,f4;
	unsigned char f12,f34;
	float LIMIT=0.0001;
	long lLineBytes;
	lpDIBBits=::FindDIBBits(lpDIB);
	lWidth=::DIBWidth(lpDIB);
	lHeight=::DIBHeight(lpDIB);
	lLineBytes=WIDTHBYTES(lWidth*8);
	i1=(long)x;
	i2=i1+1;
	j1=(long)y;
	j2=j1+1;
	if((x<0)||(x>lWidth-1)||(y<0)||(y>lHeight-1))
	{
	return 255;
	}
	else
	{ 
		if(abs(x-lWidth+1)<=LIMIT)
		{
			if(abs(y-lHeight+1)<=LIMIT)
			{
				f1=*(lpDIBBits+lLineBytes*j1+i1);
				return (unsigned char) f1;
			}
			else
			{
				f1=*(lpDIBBits+lLineBytes*j1+i1);
				f3=*(lpDIBBits+lLineBytes*j1+i2);
				return unsigned char (f1+(y-j1)*(f3-f1));
			}
		}
		else if(abs(y-lHeight+1)<=LIMIT)
		{
			f1=*(lpDIBBits+lLineBytes*j1+i1);
			f2=*(lpDIBBits+lLineBytes*j2+i1);
			return unsigned char (f1+(x-i1)*(f2-f1));
		}
		else
		{
			f1=(unsigned char )*(lpDIBBits+lLineBytes*j1+i1);
			f2=(unsigned char) *(lpDIBBits+lLineBytes*j2+i1);
			f3=(unsigned char) *(lpDIBBits+lLineBytes*j1+i2);
			f4=(unsigned char) *(lpDIBBits+lLineBytes*j2+i2);
			f12=f1+(x-i1)*(f2-f1);
			f34=f3+(x-i1)*(f4-f3);
			return unsigned char (f12+(y-j1)*(f34-f12));
		}
	}
}
//--------二值化和形态学--------
void CIRISView::Binarization()
{
	LPSTR lpDIB;
	// 指向DIB象素指针
	LPSTR lpDIBBits;
	// 锁定DIB
	CIRISDoc * pDoc=GetDocument();
	lpDIB=(LPSTR)::GlobalLock((HGLOBAL) pDoc->GetHDIB());
	// 找到DIB图像象素起始位置
	lpDIBBits=::FindDIBBits(lpDIB);
	::GlobalUnlock((HGLOBAL) pDoc->GetHDIB());
	const long lWidth=::DIBWidth(lpDIB);
	const long lHeight=::DIBHeight(lpDIB);
	//建立存储位图灰度的数组
	long threshold=Threshold(lpDIBBits,lWidth,lHeight);      
	HGLOBAL hGlobal=::GlobalAlloc(GHND,lHeight*lWidth);
	LPSTR lpRecorder=(char *)::GlobalLock(hGlobal);
	::GlobalUnlock(hGlobal);
	memset(lpRecorder,1,lHeight*lWidth);  
	//图像每行的字节数
	LONG lLineBytes;
	// 计算图像每行的字节数
	lLineBytes=WIDTHBYTES(lWidth*8);
	PupilContour(lpRecorder,lWidth,lHeight,threshold,lpDIBBits);
	CList<PHTPoint, PHTPoint&>  PointListForPHT;
	FindPHTPoint(hGlobal,&PointListForPHT,lHeight,lWidth);//找到用于PHT变换的各个点；
	if(PointListForPHT.IsEmpty())
	{
		AfxMessageBox("不是虹膜图像或者图像过于模糊无法辨别！");
		CComboBox * SingleStepComb=(CComboBox*)GetDlgItem(IDC_COMBO_SINGLESTEP);
		SingleStepComb->SetCurSel(0);
		return;
	}
	CIRCLE InnerCircle=PHT(&PointListForPHT);//PHT变换
	CIRCLE Outer=OuterCircle(lpDIBBits,lWidth,lHeight,InnerCircle);//外界圆的确定
	::GlobalFree(hGlobal);
	const long RectWidth=512;
	const long RectHeight=128;
	HDIB hDIB=TurnToRect(InnerCircle,Outer,lpDIB,RectWidth,RectHeight);
	LOGBin(hDIB);
    Morphological(hDIB);
	pDoc->CopyToTarget(hDIB);
	::GlobalFree((HGLOBAL) hDIB);
	//pDoc->CreateDIBTargetPalette();
	// 创建新调色板
	//CStatic * result=(CStatic*)GetDlgItem(IDC_STATIC_R1);
	//result->SetWindowText("二值化和形态学处理结果");
    //CDC dc;
	//OnDraw(&dc);
}
void CIRISView::LOGBin(HDIB hDIB)
{
	LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
	LPSTR lpDIBBits=::FindDIBBits(lpDIB);
	::GlobalUnlock((HGLOBAL)hDIB);
	const long lWidth=512;
	const long lHeight=128;
    //图像每行的字节数
	LONG lLineBytes;
	//计算图像每行的字节数
	lLineBytes=WIDTHBYTES(lWidth*8);
	float(*LoG)[lWidth]=new float[lHeight][lWidth];
	for(long j=0;j<lHeight;j++)
	{
		LoG[j][0]=((unsigned char)*(lpDIBBits+lLineBytes*j))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+1))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+2))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+3))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+4))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+5))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+6))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+7))*(+0.0855);
		LoG[j][1]=((unsigned char)*(lpDIBBits+lLineBytes*j+1))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+2))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+3))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+4))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+5))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+6))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+7))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+8))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j))*(-0.7420);
		LoG[j][2]=((unsigned char)*(lpDIBBits+lLineBytes*j+2))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+3))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+4))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+5))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+6))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+7))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+8))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+9))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+1))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j))*(-0.1771);
		   LoG[j][3]=((unsigned char)*(lpDIBBits+lLineBytes*j+3))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+4))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+5))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+6))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+7))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+8))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+9))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+10))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+2))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+1))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j))*(0.2913);
		LoG[j][4]=((unsigned char)*(lpDIBBits+lLineBytes*j+4))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+5))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+6))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+7))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+8))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+9))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+10))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+11))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+3))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+2))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+1))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j))*(0.4462);
		LoG[j][5]=((unsigned char)*(lpDIBBits+lLineBytes*j+5))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+6))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+7))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+8))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+9))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+10))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+11))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+12))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+4))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+3))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+2))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+1))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j))*(0.3573);
		LoG[j][6]=((unsigned char)*(lpDIBBits+lLineBytes*j+6))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+7))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+8))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+9))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+10))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+11))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+12))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+13))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+5))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+4))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+3))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+2))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+1))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j))*(0.2007);
		for(long i=7;i<lWidth-7;i++)
		{
			LoG[j][i]=((unsigned char)*(lpDIBBits+lLineBytes*j+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i+1))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i+2))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i+3))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i+4))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i+5))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i+6))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i+7))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i-1))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i-2))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i-3))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i-4))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i-5))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i-6))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+i-7))*(0.0855);		
		}
		LoG[j][lWidth-1]=((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-1))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-2))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-3))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-4))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-5))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-6))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-7))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-8))*(+0.0855);
		LoG[j][lWidth-2]=((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-2))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-3))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-4))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-5))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-6))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-7))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-8))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-9))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-1))*(-0.7420);
		LoG[j][lWidth-3]=((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-3))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-4))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-5))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-6))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-7))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-8))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-9))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-10))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-2))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-1))*(-0.1771);
		LoG[j][lWidth-4]=((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-4))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-5))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-6))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-7))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-8))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-9))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-10))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-11))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-3))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-2))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-1))*(0.2913);
		LoG[j][lWidth-5]=((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-5))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-6))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-7))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-8))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-9))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-10))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-11))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-12))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-4))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-3))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-2))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-1))*(0.4462);
		LoG[j][lWidth-6]=((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-6))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-7))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-8))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-9))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-10))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-11))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-12))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-13))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-5))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-4))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-3))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-2))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-1))*(0.3573);
		LoG[j][lWidth-7]=((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-7))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-8))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-9))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-10))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-11))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-12))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-13))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-14))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-6))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-5))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-4))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-3))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-2))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*j+lWidth-1))*(0.2007);
	}
	float (*LoGG)[lWidth]=new float[lHeight][lWidth];
	long i;
    for( i=0;i<lWidth;i++)
	{
		LoGG[0][i]=LoG[0][i]+0.9113*LoG[1][i]+0.6896*LoG[2][i]+0.4334*LoG[3][i]+0.2262*LoG[4][i]+0.0980*LoG[5][i]+0.0353*LoG[6][i]+0.0105*LoG[7][i];
		LoGG[1][i]=LoG[1][i]+0.9113*LoG[2][i]+0.6896*LoG[3][i]+0.4334*LoG[4][i]+0.2262*LoG[5][i]+0.0980*LoG[6][i]+0.0353*LoG[7][i]+0.0105*LoG[8][i]
		           +0.9113*LoG[0][i];
		LoGG[2][i]=LoG[2][i]+0.9113*LoG[3][i]+0.6896*LoG[4][i]+0.4334*LoG[5][i]+0.2262*LoG[6][i]+0.0980*LoG[7][i]+0.0353*LoG[8][i]+0.0105*LoG[9][i]+
					0.9113*LoG[1][i]+0.6896*LoG[0][i];
		LoGG[3][i]=LoG[3][i]+0.9113*LoG[4][i]+0.6896*LoG[5][i]+0.4334*LoG[6][i]+0.2262*LoG[7][i]+0.0980*LoG[8][i]+0.0353*LoG[9][i]+0.0105*LoG[10][i]+
					0.9113*LoG[2][i]+0.6896*LoG[1][i]+0.4334*LoG[0][i];
		LoGG[4][i]=LoG[4][i]+0.9113*LoG[5][i]+0.6896*LoG[6][i]+0.4334*LoG[7][i]+0.2262*LoG[8][i]+0.0980*LoG[9][i]+0.0353*LoG[10][i]+0.0105*LoG[11][i]+
					0.9113*LoG[3][i]+0.6896*LoG[2][i]+0.4334*LoG[1][i]+0.2262*LoG[0][i];
		LoGG[5][i]=LoG[5][i]+0.9113*LoG[6][i]+0.6896*LoG[7][i]+0.4334*LoG[8][i]+0.2262*LoG[9][i]+0.0980*LoG[10][i]+0.0353*LoG[11][i]+0.0105*LoG[12][i]+
					0.9113*LoG[4][i]+0.6896*LoG[3][i]+0.4334*LoG[2][i]+0.2262*LoG[1][i]+0.0980*LoG[0][i];
	    LoGG[6][i]=LoG[6][i]+0.9113*LoG[7][i]+0.6896*LoG[8][i]+0.4334*LoG[9][i]+0.2262*LoG[10][i]+0.0980*LoG[11][i]+0.0353*LoG[12][i]+0.0105*LoG[13][i]+
					0.9113*LoG[5][i]+0.6896*LoG[4][i]+0.4334*LoG[3][i]+0.2262*LoG[2][i]+0.0980*LoG[1][i]+0.0353*LoG[0][i];
	    for(long j=7;j<lHeight-7;j++)
		{  
			LoGG[j][i]=LoG[j][i]+0.9113*LoG[j+1][i]+0.6896*LoG[j+2][i]+0.4334*LoG[j+3][i]+0.2262*LoG[j+4][i]+0.0980*LoG[j+5][i]+0.0353*LoG[j+6][i]+0.0105*LoG[j+7][i]+
		         0.9113*LoG[j-1][i]+0.6896*LoG[j-2][i]+0.4334*LoG[j-3][i]+0.2262*LoG[j-4][i]+0.0980*LoG[j-5][i]+0.0353*LoG[j-6][i]+0.0105*LoG[j-7][i];
		
		}
		LoGG[lHeight-1][i]=LoG[lHeight-1][i]+0.9113*LoG[lHeight-2][i]+0.6896*LoG[lHeight-3][i]+0.4334*LoG[lHeight-4][i]+0.2262*LoG[lHeight-5][i]+0.0980*LoG[lHeight-6][i]+0.0353*LoG[lHeight-7][i]+0.0105*LoG[lHeight-8][i];
		LoGG[lHeight-2][i]=LoG[lHeight-2][i]+0.9113*LoG[lHeight-3][i]+0.6896*LoG[lHeight-4][i]+0.4334*LoG[lHeight-5][i]+0.2262*LoG[lHeight-6][i]+0.0980*LoG[lHeight-7][i]+0.0353*LoG[lHeight-8][i]+0.0105*LoG[lHeight-9][i]
							+0.9113*LoG[lHeight-1][i];
		LoGG[lHeight-3][i]=LoG[lHeight-3][i]+0.9113*LoG[lHeight-4][i]+0.6896*LoG[lHeight-5][i]+0.4334*LoG[lHeight-6][i]+0.2262*LoG[lHeight-7][i]+0.0980*LoG[lHeight-8][i]+0.0353*LoG[lHeight-9][i]+0.0105*LoG[lHeight-10][i]+
							0.9113*LoG[lHeight-2][i]+0.6896*LoG[lHeight-1][i];
		LoGG[lHeight-4][i]=LoG[lHeight-4][i]+0.9113*LoG[lHeight-5][i]+0.6896*LoG[lHeight-6][i]+0.4334*LoG[lHeight-7][i]+0.2262*LoG[lHeight-8][i]+0.0980*LoG[lHeight-9][i]+0.0353*LoG[lHeight-10][i]+0.0105*LoG[lHeight-11][i]+
							0.9113*LoG[lHeight-3][i]+0.6896*LoG[lHeight-2][i]+0.4334*LoG[lHeight-1][i];
		LoGG[lHeight-5][i]=LoG[lHeight-5][i]+0.9113*LoG[lHeight-6][i]+0.6896*LoG[lHeight-7][i]+0.4334*LoG[lHeight-8][i]+0.2262*LoG[lHeight-9][i]+0.0980*LoG[lHeight-10][i]+0.0353*LoG[lHeight-11][i]+0.0105*LoG[lHeight-12][i]+
							0.9113*LoG[lHeight-4][i]+0.6896*LoG[lHeight-3][i]+0.4334*LoG[lHeight-2][i]+0.2262*LoG[lHeight-1][i];
		LoGG[lHeight-6][i]=LoG[lHeight-6][i]+0.9113*LoG[lHeight-7][i]+0.6896*LoG[lHeight-8][i]+0.4334*LoG[lHeight-9][i]+0.2262*LoG[lHeight-10][i]+0.0980*LoG[lHeight-11][i]+0.0353*LoG[lHeight-12][i]+0.0105*LoG[lHeight-13][i]+
							0.9113*LoG[lHeight-5][i]+0.6896*LoG[lHeight-4][i]+0.4334*LoG[lHeight-3][i]+0.2262*LoG[lHeight-2][i]+0.0980*LoG[lHeight-1][i];
	    LoGG[lHeight-7][i]=LoG[lHeight-7][i]+0.9113*LoG[lHeight-8][i]+0.6896*LoG[lHeight-9][i]+0.4334*LoG[lHeight-10][i]+0.2262*LoG[lHeight-11][i]+0.0980*LoG[lHeight-12][i]+0.0353*LoG[lHeight-13][i]+0.0105*LoG[lHeight-14][i]+
							0.9113*LoG[lHeight-6][i]+0.6896*LoG[lHeight-5][i]+0.4334*LoG[lHeight-4][i]+0.2262*LoG[lHeight-3][i]+0.0980*LoG[lHeight-2][i]+0.0353*LoG[lHeight-1][i];
	}
	float LoGy[lHeight][lWidth];
	for(long i=0;i<lWidth;i++)
	{
		LoGy[0][i]=((unsigned char)*(lpDIBBits+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*1+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*2+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*3+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*4+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*5+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*6+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*7+i))*(+0.0855);
		LoGy[1][i]=((unsigned char)*(lpDIBBits+lLineBytes*1+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*2+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*3+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*4+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*5+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*6+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*7+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*8+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+i))*(-0.7420);
		LoGy[2][i]=((unsigned char)*(lpDIBBits+lLineBytes*2+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*3+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*4+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*5+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*6+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*7+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*8+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*9+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*1+i))*(-0.1771);
		LoGy[3][i]=((unsigned char)*(lpDIBBits+lLineBytes*3+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*4+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*5+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*6+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*7+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*8+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*9+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*10+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*1+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*2+i))*(0.2913);
		LoGy[4][i]=((unsigned char)*(lpDIBBits+lLineBytes*4+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*5+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*6+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*7+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*8+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*9+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*10+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*11+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*1+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*2+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*3+i))*(0.4462);
		LoGy[5][i]=((unsigned char)*(lpDIBBits+lLineBytes*5+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*6+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*7+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*8+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*9+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*10+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*11+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*12+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*1+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*2+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*3+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*4+i))*(0.3573);
		LoGy[6][i]=((unsigned char)*(lpDIBBits+lLineBytes*6+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*7+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*8+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*9+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*10+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*11+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*12+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*13+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*14+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*5+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*4+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*3+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*2+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes+i))*(0.2007);
		for(long j=7;j<lHeight-7;j++)
		{
           LoGy[j][i]=((unsigned char)*(lpDIBBits+lLineBytes*j+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j+1)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j+2)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j+3)+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j+4)+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j+5)+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j+6)+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j+7)+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j-1)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j-2)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j-3)+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j-4)+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j-5)+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j-6)+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(j-7)+i))*(0.0855);
		}
		LoGy[lHeight-1][i]=((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-1)+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-2)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-3)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-4)+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-5)+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-6)+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-7)+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-8)+i))*(+0.0855);
		LoGy[lHeight-2][i]=((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-2)+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-3)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-4)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-5)+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-6)+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-7)+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-8)+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-9)+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-1)+i))*(-0.7420);
		LoGy[lHeight-3][i]=((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-3)+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-4)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-5)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-6)+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-7)+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-8)+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-9)+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-10)+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-2)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-1)+i))*(-0.1771);
		LoGy[lHeight-4][i]=((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-4)+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-5)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-6)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-7)+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-8)+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-9)+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-10)+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-11)+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-3)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-2)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-1)+i))*(0.2913);
		LoGy[lHeight-5][i]=((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-5)+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-6)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-7)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-8)+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-9)+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-10)+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-11)+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-12)+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-4)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-3)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-2)+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-1)+i))*(0.4462);
		LoGy[lHeight-6][i]=((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-6)+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-7)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-8)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-9)+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-10)+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-11)+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-12)+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-13)+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-5)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-4)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-3)+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-2)+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-1)+i))*(0.3573);
		LoGy[lHeight-7][i]=((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-7)+i))*(-1)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-8)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-9)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-10)+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-11)+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-12)+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-13)+i))*(0.2007)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-14)+i))*(+0.0855)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-6)+i))*(-0.7420)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-5)+i))*(-0.1771)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-4)+i))*(0.2913)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-3)+i))*(0.4462)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-2)+i))*(0.3573)+
		  ((unsigned char)*(lpDIBBits+lLineBytes*(lHeight-1)+i))*(0.2007);

	}
	float LoGGy[lHeight][lWidth];
    for(long j=0;j<lHeight;j++)
	{
		LoGGy[j][0]=LoGy[j][0]+0.9113*LoGy[j][1]+0.6896*LoGy[j][2]+0.4334*LoGy[j][3]+0.2262*LoGy[j][4]+0.0980*LoGy[j][5]+0.0353*LoGy[j][6]+0.0105*LoGy[j][7];
		LoGGy[j][1]=LoGy[j][1]+0.9113*LoGy[j][2]+0.6896*LoGy[j][3]+0.4334*LoGy[j][4]+0.2262*LoGy[j][5]+0.0980*LoGy[j][6]+0.0353*LoGy[j][7]+0.0105*LoGy[j][8]
					+0.9113*LoGy[j][0];
		LoGGy[j][2]=LoGy[j][2]+0.9113*LoGy[j][3]+0.6896*LoGy[j][4]+0.4334*LoGy[j][5]+0.2262*LoGy[j][6]+0.0980*LoGy[j][7]+0.0353*LoGy[j][8]+0.0105*LoGy[j][9]+
					0.9113*LoGy[j][1]+0.6896*LoGy[j][0];
		LoGGy[j][3]=LoGy[j][3]+0.9113*LoGy[j][4]+0.6896*LoGy[j][5]+0.4334*LoGy[j][6]+0.2262*LoGy[j][7]+0.0980*LoGy[j][8]+0.0353*LoGy[j][9]+0.0105*LoGy[j][10]+
					0.9113*LoGy[j][2]+0.6896*LoGy[j][1]+0.4334*LoGy[j][0];
		LoGGy[j][4]=LoGy[j][4]+0.9113*LoGy[j][5]+0.6896*LoGy[j][6]+0.4334*LoGy[j][7]+0.2262*LoGy[j][8]+0.0980*LoGy[j][9]+0.0353*LoGy[j][10]+0.0105*LoGy[j][11]+
					0.9113*LoGy[j][3]+0.6896*LoGy[j][2]+0.4334*LoGy[j][1]+0.2262*LoGy[j][0];
		LoGGy[j][5]=LoGy[j][5]+0.9113*LoGy[j][6]+0.6896*LoGy[j][7]+0.4334*LoGy[j][8]+0.2262*LoGy[j][9]+0.0980*LoGy[j][10]+0.0353*LoGy[j][11]+0.0105*LoGy[j][12]+
					0.9113*LoGy[j][4]+0.6896*LoGy[j][3]+0.4334*LoGy[j][2]+0.2262*LoGy[j][1]+0.0980*LoGy[j][0];
	    LoGGy[j][6]=LoGy[j][6]+0.9113*LoGy[j][7]+0.6896*LoGy[j][8]+0.4334*LoGy[j][9]+0.2262*LoGy[j][10]+0.0980*LoGy[j][11]+0.0353*LoGy[j][12]+0.0105*LoGy[j][13]+
					0.9113*LoGy[j][5]+0.6896*LoGy[j][4]+0.4334*LoGy[j][3]+0.2262*LoGy[j][2]+0.0980*LoGy[j][1]+0.0353*LoGy[j][0];
	    for(long i=7;i<lWidth-7;i++)
		{  
			LoGGy[j][i]=LoGy[j][i]+0.9113*LoGy[j][i+1]+0.6896*LoGy[j][i+2]+0.4334*LoGy[j][i+3]+0.2262*LoGy[j][i+4]+0.0980*LoGy[j][i+5]+0.0353*LoGy[j][i+6]+0.0105*LoGy[j][i+7]+
		         0.9113*LoGy[j][i-1]+0.6896*LoGy[j][i-2]+0.4334*LoGy[j][i-3]+0.2262*LoGy[j][i-4]+0.0980*LoGy[j][i-5]+0.0353*LoGy[j][i-6]+0.0105*LoGy[j][i-7];
		}
		LoGGy[j][lWidth-1]=LoGy[j][lWidth-1]+0.9113*LoGy[j][lWidth-2]+0.6896*LoGy[j][lWidth-3]+0.4334*LoGy[j][lWidth-4]+0.2262*LoGy[j][lWidth-5]+0.0980*LoGy[j][lWidth-6]+0.0353*LoGy[j][lWidth-7]+0.0105*LoGy[j][lWidth-8];
		LoGGy[j][lWidth-2]=LoGy[j][lWidth-2]+0.9113*LoGy[j][lWidth-3]+0.6896*LoGy[j][lWidth-4]+0.4334*LoGy[j][lWidth-5]+0.2262*LoGy[j][lWidth-6]+0.0980*LoGy[j][lWidth-7]+0.0353*LoGy[j][lWidth-8]+0.0105*LoGy[j][lWidth-9]
							+0.9113*LoGy[j][lWidth-1];
		LoGGy[j][lWidth-3]=LoGy[j][lWidth-3]+0.9113*LoGy[j][lWidth-4]+0.6896*LoGy[j][lWidth-5]+0.4334*LoGy[j][lWidth-6]+0.2262*LoGy[j][lWidth-7]+0.0980*LoGy[j][lWidth-8]+0.0353*LoGy[j][lWidth-9]+0.0105*LoGy[j][lWidth-10]+
							0.9113*LoGy[j][lWidth-2]+0.6896*LoGy[j][lWidth-1];
		LoGGy[j][lWidth-4]=LoGy[j][lWidth-4]+0.9113*LoGy[j][lWidth-5]+0.6896*LoGy[j][lWidth-6]+0.4334*LoGy[j][lWidth-7]+0.2262*LoGy[j][lWidth-8]+0.0980*LoGy[j][lWidth-9]+0.0353*LoGy[j][lWidth-10]+0.0105*LoGy[j][lWidth-11]+
							0.9113*LoGy[j][lWidth-3]+0.6896*LoGy[j][lWidth-2]+0.4334*LoGy[j][lWidth-1];
		LoGGy[j][lWidth-5]=LoGy[j][lWidth-5]+0.9113*LoGy[j][lWidth-6]+0.6896*LoGy[j][lWidth-7]+0.4334*LoGy[j][lWidth-8]+0.2262*LoGy[j][lWidth-9]+0.0980*LoGy[j][lWidth-10]+0.0353*LoGy[j][lWidth-11]+0.0105*LoGy[j][lWidth-12]+
							0.9113*LoGy[j][lWidth-4]+0.6896*LoGy[j][lWidth-3]+0.4334*LoGy[j][lWidth-2]+0.2262*LoGy[j][lWidth-1];
        LoGGy[j][lWidth-6]=LoGy[j][lWidth-6]+0.9113*LoGy[j][lWidth-7]+0.6896*LoGy[j][lWidth-8]+0.4334*LoGy[j][lWidth-9]+0.2262*LoGy[lHeight-10][i]+0.0980*LoGy[lHeight-11][i]+0.0353*LoGy[lHeight-12][i]+0.0105*LoGy[lHeight-13][i]+
							0.9113*LoGy[j][lWidth-5]+0.6896*LoGy[j][lWidth-4]+0.4334*LoGy[j][lWidth-3]+0.2262*LoGy[j][lWidth-2]+0.0980*LoGy[j][lWidth-1];
		LoGGy[j][lWidth-7]=LoGy[j][lWidth-7]+0.9113*LoGy[j][lWidth-8]+0.6896*LoGy[j][lWidth-9]+0.4334*LoGy[j][lWidth-10]+0.2262*LoGy[j][lWidth-11]+0.0980*LoGy[j][lWidth-12]+0.0353*LoGy[j][lWidth-13]+0.0105*LoGy[j][lWidth-14]+
							0.9113*LoGy[j][lWidth-6]+0.6896*LoGy[j][lWidth-5]+0.4334*LoGy[j][lWidth-4]+0.2262*LoGy[j][lWidth-3]+0.0980*LoGy[j][lWidth-2]+0.0353*LoGy[j][lWidth-1];
	}
	for(long j=0;j<lHeight;j++)
	{
		for(long i=0;i<lWidth;i++)
		{
			LoGG[j][i]=LoGG[j][i]+LoGGy[j][i];
		}
	}
    for(long j=0;j<lHeight;j++)
	{
        int marker=0;
		for (long i=0;i<lWidth;i++)
		{
			if(LoGG[j][i]>0)
			{
				marker=1;
				*(lpDIBBits+lLineBytes*j+i)=(unsigned char)255;
			}
			if(LoGG[j][i]<0)
			{
				marker=0;
				*(lpDIBBits+lLineBytes*j+i)=(unsigned char)0;
			}
			if(LoGG[j][i]==0)
			{
				if(marker==1)
					*(lpDIBBits+lLineBytes*j+i)=(unsigned char)255;
				else *(lpDIBBits+lLineBytes*j+i)=(unsigned char)0;
			}
		}
	}
	delete[] LoG;
	delete[] LoGG;
}
//形态学处理
void CIRISView::Morphological(HDIB hDIB)
{
/*
本函数默认hDIB的大小为512×128；
对图像做闭运算，所用的结构元为
。 。 。
。 。 。
。 。 。
如果不同，应做相应处理
*/
	LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
	LPSTR lpDIBBits=::FindDIBBits(lpDIB);
	::GlobalUnlock((HGLOBAL)hDIB);
	const long lWidth=512;
	const long lHeight=128;
    // 图像每行的字节数
	LONG lLineBytes;
	// 计算图像每行的字节数
    int m=3;
    int n=3;
	int structure[3][3]={0,0,0,0,0,0,0,0,0};
	//循环变量
	long i;
	long j;
	//指向源图像的指针
	LPSTR	lpSrc;
	// 指向缓存图像的指针
	LPSTR	lpDst;
	// 指向缓存DIB图像的指针
	LPSTR	lpNewDIBBits;
	HLOCAL	hNewDIBBits;
	//像素值
	unsigned char pixel;
	// 暂时分配内存，以保存新图像
	hNewDIBBits=LocalAlloc(LHND,lWidth*lHeight);
	if(hNewDIBBits==NULL)
	{
		//分配内存失败
		AfxMessageBox("内存分配失败！");
		return ;
	}
	// 锁定内存
	lpNewDIBBits=(char *)LocalLock(hNewDIBBits);
	// 初始化新分配的内存，设定初始值为0
	lpDst=(char *)lpNewDIBBits;
	memset(lpDst,(BYTE)0,lWidth*lHeight);
	//使用自定义的结构元素进行腐蚀
	for(j=1;j<lHeight-1;j++)
	{
		for(i=1;i<lWidth-1;i++)
		{
			//由于使用3×3的结构元素，为防止越界，所以不处理最左边和最右边的两列像素
			//和最上边和最下边的两列像素
			//指向源图像倒数第j行，第i个象素的指针			
			lpSrc=(char *)lpDIBBits+lWidth*j+i;
			// 指向目标图像倒数第j行，第i个象素的指针			
			lpDst=(char *)lpNewDIBBits+lWidth*j + i;
			//取得当前指针处的像素值，注意要转换为unsigned char型
			pixel=(unsigned char)*lpSrc;
			//目标图像中含有0和255外的其它灰度值
			if(pixel!=255&&*lpSrc!=0)
			{  
				AfxMessageBox("非二值图像!");
				return ;
			}
			*lpDst=(unsigned char)255;
			//原图像中对应结构元素中为黑色的那些点中只要有一个是黑色，
			//则将目标图像中的当前点赋成黑色
			//注意在DIB图像中内容是上下倒置的
			for(m=0;m<3;m++ )
			{
				for(n=0;n<3;n++)
				{
					if(structure[m][n]==-1)
						continue;
					pixel=*(lpSrc+((2-m)-1)*lWidth+(n-1));
					if(pixel==0)
					{	
						*lpDst=(unsigned char)0;
						break;
					}
				}
			}	
		}
	}
    //复制腐蚀后的图像
	memcpy(lpDIBBits,lpNewDIBBits,lWidth*lHeight);
	lpDst=(char *)lpNewDIBBits;
    memset(lpDst,(BYTE)0,lWidth*lHeight);
	//使用自定义的结构元素进行膨胀
	for(j=1;j<lHeight-1;j++)
	{
		for(i=1;i<lWidth-1;i++)
		{
			//由于使用3×3的结构元素，为防止越界，所以不处理最左边和最右边的两列像素
			//和最上边和最下边的两列像素
			// 指向源图像倒数第j行，第i个象素的指针			
			lpSrc=(char *)lpDIBBits+lWidth*j+i;
			// 指向目标图像倒数第j行，第i个象素的指针			
			lpDst=(char *)lpNewDIBBits+lWidth*j+i;
			//取得当前指针处的像素值，注意要转换为unsigned char型
			pixel=(unsigned char)*lpSrc;
			//目标图像中含有0和255外的其它灰度值
			if(pixel!=255&&*lpSrc!=0)
			{
				AfxMessageBox("非二值图像！");
				return ;
			}
			//目标图像中的当前点先赋成黑色
			*lpDst=(unsigned char)0;
			//如果原图像中对应结构元素中为黑色的那些点中有一个不是黑色，
			//则将目标图像中的当前点赋成白色
			//注意在DIB图像中内容是上下倒置的
			for(m=0;m<3;m++ )
			{
				for(n=0;n<3;n++)
				{
					if(structure[m][n]==-1)
						continue;
					pixel=*(lpSrc+((2-m)-1)*lWidth+(n-1));
					if(pixel==255)
					{	
						*lpDst=(unsigned char)255;
						break;
					}
				}
			}
		}
	}
	//复制膨胀后的图像
	memcpy(lpDIBBits,lpNewDIBBits,lWidth*lHeight);
	//释放内存
	LocalUnlock(hNewDIBBits);
	LocalFree(hNewDIBBits);
}

//---------特征点的采集和处理-----
//得到特征点
//PointInformation特征点的存储
//tab多少个
void CIRISView::MarkthePoint(HDIB hDIB,PointInformation *PointInfor,int &tab)
{
	LPSTR lpDIB=(LPSTR)::GlobalLock((HGLOBAL)hDIB);
	LPSTR lpDIBBits=::FindDIBBits(lpDIB);
	::GlobalUnlock((HGLOBAL)hDIB);
	const long lWidth=512;
	const long lHeight=128;
    // 图像每行的字节数
	LONG lLineBytes;
	// 计算图像每行的字节数
	lLineBytes=WIDTHBYTES(lWidth*8);
	int taber=0;//标记点个数
	LPSTR src=lpDIBBits;
	unsigned char pre=*src;
	for(int i=0;i<255;i++)
	{
		PointInfor[i].useful=false;
	}
	if(pre==255)
	{//如果刚开始源地址为255情况标记为有用
		PointInfor[1].left=0;
		PointInfor[1].right=0;
		PointInfor[1].bottom=0;
		PointInfor[1].top=0;
		PointInfor[1].useful=true;
		PointInfor[1].xsum=0;
		PointInfor[1].ysum=0;
		PointInfor[1].size=1;
		*src=1;
		taber=taber+1;
	}
	CList<long,long> unusedtab;	
	long i;	
	//处理第一行
	for(i=1;i<lWidth;i++)
	{
		src=lpDIBBits+i;
		if((unsigned char)*src==255)
		{ 
			if(pre!=0)
			{
				*src=(unsigned char)pre;
				PointInfor[(unsigned long)*src].right=i;
				PointInfor[(unsigned long)*src].size+=1;
				PointInfor[(unsigned long)*src].xsum+=i;
			 }
			else
			{
				tab=tab+1;
				if(tab>=255)
				{
					tab=255;
					*src=0;//忽略该点，将该点涂黑，以下同
				}
				else//特征区域断开，新的特征区域
				{
				*src=(unsigned char)taber+1;
				PointInfor[taber].useful=true;
                PointInfor[taber].top=0;
				PointInfor[taber].bottom=0;
				PointInfor[taber].left=i;
				PointInfor[taber].right=i;
				PointInfor[taber].size=1;
				PointInfor[taber].xsum=i;
				PointInfor[taber].ysum=0;
				}
			 }
		 }
		 pre=*src;
	}

	for(long j=1;j<lHeight;j++)
	{
		//处理第一列
		LPSTR src_a=lpDIBBits+(j-1)*lLineBytes;
		LPSTR src=lpDIBBits+j*lLineBytes;
		if(*src=255)
		{ 
			if(*src_a!=0)
		    {
				*src=*src_a;
			    PointInfor[(unsigned long)*src_a].bottom=j;
			    PointInfor[(unsigned long)*src_a].size+=1;
			    PointInfor[(unsigned long)*src_a].ysum+=j;
		    }
			else
		    {   
				if(unusedtab.IsEmpty()!=true)
				{   
					long t=(unsigned char)unusedtab.GetHead();
					*src=t;
					unusedtab.RemoveHead();
					PointInfor[t].useful=true;
					PointInfor[t].left=i;
				    PointInfor[t].right=i;
				    PointInfor[t].top=j;
				    PointInfor[t].bottom=j;
				    PointInfor[t].size=1;
					PointInfor[t].xsum=0;
					PointInfor[t].ysum=j;
				}
				else
		        {
					taber=taber+1;
					if(taber>=255)
					{
						taber=255;
						*src=0;
					}
					else
					{
						*src=(unsigned char)taber;
						PointInfor[taber].useful=true;
						PointInfor[taber].left=i;
						PointInfor[taber].right=i;
						PointInfor[taber].top=j;
						PointInfor[taber].bottom=j;
						PointInfor[taber].size=1;
						PointInfor[taber].xsum=i;
						PointInfor[taber].ysum=j;
					}
				}
				 
			}
			//处理全部区域
			for(long i=1;i<lWidth;i++)
			{
				LPSTR  src_a=lpDIBBits+lLineBytes*(j-1)+i-1;
				LPSTR  src_b=lpDIBBits+lLineBytes*(j-1)+i;
				LPSTR  src_c=lpDIBBits+lLineBytes*j+i-1;
				LPSTR  src=lpDIBBits+lLineBytes*j+i;
				if(*src==0)
					continue;
				if(*src!=0)
				{
					//a没有被标记的情况
					if(*src_a!=0)
					{ 
						*src=*src_a;
						long point=(unsigned char)*src;
						if(PointInfor[point].right<i)
							PointInfor[point].right=i;
						PointInfor[point].size+=1;
						if(PointInfor[point].bottom<j)
							PointInfor[point].bottom=j;
						PointInfor[point].xsum+=i;
						PointInfor[point].ysum+=j;
							continue;
					}
					//b或者c已经标记过的
					if(*src_b!=0&&*src_c==0)
					{
						*src=*src_b;
						long point=(unsigned char)*src;
						if(PointInfor[point].right<i)
							PointInfor[point].right=i;
						PointInfor[point].size+=1;
						if(PointInfor[point].bottom<j)
							PointInfor[point].bottom=j;
						PointInfor[point].xsum+=i;
						PointInfor[point].ysum+=j;
						continue;
					}
					if(*src_b==0&&*src_c!=0)
					{
						*src=*src_c;
						long point=(unsigned char)*src;
						if(PointInfor[point].right<i)
							PointInfor[point].right=i;
						PointInfor[point].size+=1;
						if(PointInfor[point].bottom<j)
							PointInfor[point].bottom=j;
						PointInfor[point].xsum+=i;
						PointInfor[point].ysum+=j;
						continue;
					}
					//bc已经标记过的且标记相同
					if(*src_b!=0&&*src_c!=0&&*src_b==*src_c)
					{
						*src=*src_c;
						long point=(unsigned char)*src;
						if(PointInfor[point].right<i)
							PointInfor[point].right=i;
						PointInfor[point].size+=1;
						if(PointInfor[point].bottom<j)
							PointInfor[point].bottom=j;
						PointInfor[point].xsum+=i;
						PointInfor[point].ysum+=j;
						continue;
					}
					//bc已经标记过的且标记不同
					if(*src_b!=0&&*src_c!=0&&*src_b!=*src_c)
					{
					*src=((unsigned char)*src_b<(unsigned char)*src_c)?(unsigned char)*src_b:(unsigned char) *src_c;
					long tmp=((unsigned char)*src_b<(unsigned char)*src_c)? (unsigned char)*src_c:(unsigned char)*src_b;
					if(PointInfor[(unsigned char)*src_c].left<PointInfor[(unsigned char)*src_b].left)
						PointInfor[(unsigned char)*src].left=PointInfor[(unsigned char)*src_c].left;
					else
						PointInfor[(unsigned char)*src].left=PointInfor[(unsigned char)*src_b].left;
					if(PointInfor[(unsigned char)*src_c].top<PointInfor[(unsigned char)*src_b].top)
						PointInfor[(unsigned char)*src].top=PointInfor[(unsigned char)*src_c].top;
					else 
						PointInfor[(unsigned char)*src].top=PointInfor[(unsigned char)*src_b].top;
					if(PointInfor[(unsigned char)*src_c].right>PointInfor[(unsigned char)*src_b].right)
						PointInfor[(unsigned char)*src].right=PointInfor[(unsigned char)*src_c].right;
					else
						PointInfor[(unsigned char)*src].right=PointInfor[(unsigned char)*src_b].right;
					if(PointInfor[(unsigned char)*src].right<i)
						PointInfor[(unsigned char)*src].right=i;
					PointInfor[(unsigned char)*src].bottom=j;
					PointInfor[(unsigned char)*src].size=PointInfor[(unsigned char)*src_b].size+PointInfor[(unsigned char)*src_c].size+1;
					PointInfor[(unsigned char)*src].xsum=PointInfor[(unsigned char)*src_b].xsum+PointInfor[(unsigned char)*src_c].xsum+i;
					PointInfor[(unsigned char)*src].ysum=PointInfor[(unsigned char)*src_b].ysum+PointInfor[(unsigned char)*src_c].ysum+j;
					for(long k=PointInfor[tmp].top;k<=PointInfor[tmp].bottom;k++)
					{  
						for(long l=PointInfor[tmp].left;l<=PointInfor[tmp].right;l++)
						{
							LPSTR src1=lpDIBBits+lLineBytes*k+l;
							if((unsigned char)*src1==(unsigned char)tmp)
							*src1=*src;
						}
					}
					PointInfor[tmp].useful=false;
					PointInfor[tmp].left=0;
					PointInfor[tmp].bottom=0;
					PointInfor[tmp].right=0;
					PointInfor[tmp].top=0;
					PointInfor[tmp].size=0;
					PointInfor[tmp].xsum=0;
					PointInfor[tmp].ysum=0;
					unusedtab.AddTail(tmp);
					continue;
					}
					//bc都没有被标记
					if(*src_b==0&&*src_c==0)
					{
						if(unusedtab.IsEmpty()!=true)
						{
							*src=(unsigned char)unusedtab.GetHead();
							unusedtab.RemoveHead();
							PointInfor[(unsigned char )*src].useful=true;
							PointInfor[(unsigned char )*src].top=j;
							PointInfor[(unsigned char )*src].bottom=j;
							PointInfor[(unsigned char )*src].left=i;
							PointInfor[(unsigned char )*src].right=i;
							PointInfor[(unsigned char )*src].size=1;
							PointInfor[(unsigned char )*src].xsum=i;
							PointInfor[(unsigned char )*src].ysum=j;
							continue;
						}
						else
						{
							taber=taber+1;
							if(taber>=255)
							{
								taber=255;
								*src=0;
							}else
							{
								*src=(unsigned char)taber;
								PointInfor[(unsigned char )*src].useful=true;
								PointInfor[(unsigned char )*src].top=j;
								PointInfor[(unsigned char )*src].bottom=j;
								PointInfor[(unsigned char )*src].left=i;
								PointInfor[(unsigned char )*src].right=i;
								PointInfor[(unsigned char )*src].size=1;
								PointInfor[(unsigned char )*src].xsum=i;
								PointInfor[(unsigned char )*src].ysum=j;
								continue;
							}
						}
				 
					}
				}
			}
		}
	}
	tab=taber;
 }
 //得到特征向量
 //PointInformation特征点的存储
 //tab多少个
 //CharacterVector特征向量的转化
void CIRISView::GetCharacterVector(PointInformation * PointInfor,int tab,CharacterVector *Character,int length)
{    
	const long lWidth=512;
	const long lHeight=128;
	//图像每行的字节数
	LONG lLineBytes;
	//计算图像每行的字节数
	lLineBytes=WIDTHBYTES(lWidth*8);
    HGLOBAL hGlobal=::GlobalAlloc(GHND,lHeight*lWidth);
	LPSTR lpRecorder=(char*)::GlobalLock(hGlobal);
	::GlobalUnlock(hGlobal);
	memset(lpRecorder,0,lHeight*lWidth);  
	for(int i=1;i<=tab;i++)
	{  
		if(PointInfor[i].useful)
		{
			if(PointInfor[i].top<5&&((PointInfor[i].right-PointInfor[i].left)>80))
			{//去除下侧干扰点（虹膜内边缘部分）
				PointInfor[i].useful=false;
				PointInfor[i].top=0;
				PointInfor[i].bottom=0;
				PointInfor[i].right=0;
				PointInfor[i].bottom=0;
				PointInfor[i].size=0;
				PointInfor[i].xsum=0;
				PointInfor[i].ysum=0;
				 continue;
			}
			if(PointInfor[i].bottom>98&&((PointInfor[i].bottom-PointInfor[i].top)>45||(PointInfor[i].right-PointInfor[i].left)>80))	 
			{//去除眼皮和睫毛的干扰
				PointInfor[i].useful=false;
				PointInfor[i].top=0;
				PointInfor[i].bottom=0;
				PointInfor[i].right=0;
				PointInfor[i].bottom=0;
				PointInfor[i].size=0;
				PointInfor[i].xsum=0;
				PointInfor[i].ysum=0;
				continue;
			}
			PointInfor[i].xsum=(float)PointInfor[i].xsum/(float)PointInfor[i].size+0.5;
			PointInfor[i].ysum=(float)PointInfor[i].ysum/(float)PointInfor[i].size+0.5;
			LPSTR src2= lpRecorder+lLineBytes*PointInfor[i].ysum+PointInfor[i].xsum;
			*src2=i;
		}
	}
	for(int i=0;i<length;i++)
	{
		Character[i].type=0;
	}
	int counter=0;
	for(long j=0;j<lHeight;j++)
	{
		for(long i=0;i<lWidth;i++)
		{
			LPSTR src3;
			src3=lpRecorder+lLineBytes*j+i;
			int src_val=(unsigned char)*src3;
			if(src_val!=0)
			{   
				Character[counter].left=PointInfor[src_val].left;
				Character[counter].bottom=PointInfor[src_val].bottom;
				Character[counter].top=PointInfor[src_val].top;
				Character[counter].right=PointInfor[src_val].right;
				Character[counter].x=PointInfor[src_val].xsum;
				Character[counter].y=PointInfor[src_val].ysum;
				int dy=PointInfor[src_val].bottom-PointInfor[src_val].top;
				int dx=PointInfor[src_val].right-PointInfor[src_val].left;
				float dydx=(float)dy/(float)dx+0.5;
				float area_ratio=(float) PointInfor[src_val].size/(float)(dx*dy);
				if(area_ratio<=0.5)
				{ 
					if(PointInfor[src_val].size<100)
						Character[counter].type=9;
					else
						Character[counter].type=8;

				}
				else
				{ 
					if(dydx<2&&dydx>0.5)
					{
						if(PointInfor[src_val].size<40)
							Character[counter].type=1;
						if(PointInfor[src_val].size<160&&PointInfor[src_val].size>=40)
							Character[counter].type=2;
						if(PointInfor[src_val].size>=160)
							Character[counter].type=3;
					}
					if(dydx>=2)
					{   
						if(PointInfor[src_val].size<40)
							Character[counter].type=10;
						if(PointInfor[src_val].size<160&&PointInfor[src_val].size>=60)
							Character[counter].type=4;
						if(PointInfor[src_val].size>=160)
							Character[counter].type=5;
					}
					if(dydx<=0.5)
					{     
						if(PointInfor[src_val].size<40)
                          Character[counter].type=11;
					    if(PointInfor[src_val].size<160&&PointInfor[src_val].size>=60)
						  Character[counter].type=6;
					  if(PointInfor[src_val].size>=160)
						  Character[counter].type=7;
					}
				}
				counter++;
				if(counter>=length)
				{  
					::GlobalFree(hGlobal);
					return ;
				}
			}
			else
			{
				Character[counter].left = 0;
				Character[counter].bottom = 0;
				Character[counter].top = 0;
				Character[counter].right = 0;
				Character[counter].x = 0;
				Character[counter].y = 0;
			}
		}
	}
	if (counter < length-1)
	{
		for (int i = counter + 1; i < length; i++)
		{
			Character[i].left = 0;
			Character[i].bottom = 0;
			Character[i].top = 0;
			Character[i].right = 0;
			Character[i].x = 0;
			Character[i].y = 0;
		}
	}
	::GlobalFree(hGlobal);
}
//-----------二张图片的对比---------
float CIRISView::Compare(CharacterVector *chara1,CharacterVector* chara2,int Vect1,int Vect2)
{     
	const long lWidth=512;
	const long lHeight=128;
	HGLOBAL	hGlobal=::GlobalAlloc(GHND,lHeight*lWidth);
	LPSTR lpRecorder=(char*)::GlobalLock(hGlobal);
	::GlobalUnlock(hGlobal);
	LONG lLineBytes=WIDTHBYTES(lWidth*8);
	memset(lpRecorder,(unsigned char)255,lHeight*lWidth); 
	for(int i=0;i<Vect2;i++)
	{
		if(chara2[i].type!=0)
		{
			LPSTR src=lpRecorder+chara2[i].y*lLineBytes+chara2[i].x;
			*src=(unsigned char)i;
		}
	}
	int maxmatchednum=0;
	for(int angle=-42;angle<42;angle++)
	{
		for(int updown=-5;updown<5;updown++)
		{
          int matchednum=0;
	      bool matched=false;
	      for(int m=0;m<Vect1;m++)
	      {
			matched=false;
			if(chara1[m].type!=0)
			{  
				long t1=chara1[m].top-updown*0.02*chara1[m].top+0.5;
				long t2=chara1[m].bottom-updown*0.02*chara1[m].bottom+0.5;
                if(t1<0)
					t1=0;
				if(t2>lHeight-1)
					t2=lHeight-1;
	            for(long j=t1;j<=t2;j++)
	            {   
					if(matched)
	                   break;
					for(long i=chara1[m].left;i<chara1[m].right;i++)
					{   
						long t=(i+angle)%lWidth;
			            unsigned char  number=*(lpRecorder+lLineBytes*j+t);
			            if(number!=255)
						{
							if(chara2[number].type==chara1[m].type)
							{     
								matched=true;
								matchednum+=1;
								break;
							}
						}
					}
				}
			}
		  }
		  if(matchednum>maxmatchednum)
			  maxmatchednum=matchednum;
		}
	} 
	::GlobalFree(hGlobal);
	int chara1num=0;
	int chara2num=0;
	for(int i=0;i<Vect1;i++)
	{
		if(chara1[i].type!=0)
			chara1num++;
	}
	for(int i=0;i<Vect2;i++)
	{
		if(chara2[i].type!=0)
			chara2num++;
	}
	float lamuda=(float)maxmatchednum/(float)(chara2num+chara1num); 
	return  2*lamuda;
}
//保存特征向量
void CIRISView::MySaveCharaV(FileName_Chara FileName_CharaVx,int Vect)
{
	char *filename=(LPSTR)(LPCTSTR)FileName_CharaVx.FileName;
	FILE *fp=fopen(filename,"a+");
	if(fp==NULL)
	{
		return;
	}
	for(int i=0;i<Vect;i++)
	{
		fprintf(fp,"%4u %4u %4u %4u %4u %4u %4u\n",FileName_CharaVx.Chara[i].left,FileName_CharaVx.Chara[i].right,
			FileName_CharaVx.Chara[i].top,FileName_CharaVx.Chara[i].bottom,FileName_CharaVx.Chara[i].type,
			FileName_CharaVx.Chara[i].x,FileName_CharaVx.Chara[i].y);
	}
	fclose(fp);
}



void CIRISView::OnBnClickedButtonSelecttarget2()
{
	// TODO:  在此添加控件通知处理程序代码
}
